Ich bin etwas verwirrt von #define
Aussagen. In Bibliotheken scheinen sie ein Kommunikationsmittel zwischen verschiedenen Dateien zu sein, mit vielen #ifdef
s und #ifndef
s.
Allerdings habe ich jetzt zwei Dateien file1.c
und file2.c
zusammen zusammengestellt, mit #define TEST 10
Innerhalb file2.c
. Doch wenn ich benutze TEST
Innerhalb file2.c
der Compiler gibt folgende Fehlermeldung:
'TEST' undeclared (first use in this function)
Gibt #define
Richtlinien global?
#define
s sind nicht global, sie sind nur eine Substitution, wo immer sie verwendet werden (wenn sie in derselben Kompiliereinheit deklariert sind).
Sie sind nicht Globalisten, das sind sie nicht Symbole, das sind sie irrelevant bei der Verknüpfung sind sie nur bei relevant Vorkompilierung.
#define
d-Makros sind insofern global, als sie nicht den normalen C-Scoping-Regeln folgen. Die textuelle Ersetzung aus dem Makro wird (fast) angewendet irgendwo der Makroname erscheint nach seinem #define
. (Bemerkenswerte Ausnahmen sind, wenn der Makroname Teil eines Kommentars oder Teil eines Zeichenfolgenliterals ist.)
Wenn Sie ein Makro in einer Header-Datei definieren, kann jede Datei, die #include
s diese Header-Datei wird dieses Makro erben (ob gewünscht oder nicht), es sei denn, die Datei definiert es danach explizit mit #undef
.
In deinem Beispiel file2.c
weiß nichts über die TEST
Makro. Wie würde es wissen, um die abzuholen #define
aus file1.c
? Durch Magie? Da Makros eine textuelle Substitution des Quellcodes durchführen, gibt es keine Darstellung von ihnen in den generierten Objektdateien. file2.c
Daher muss diese Substitutionsregel selbst bekannt sein, und wenn Sie möchten, dass sie von mehreren Dateien gemeinsam genutzt wird, dann #define
muss in einer gemeinsamen Header-Datei leben, die Ihre .c
Dateien #include
.
Wenn Sie speziell fragen, wie viele der #ifdef
s, die Sie in Bibliotheken sehen, prüfen viele von ihnen wahrscheinlich vordefiniert Makronamen, die von der Kompilierungsumgebung bereitgestellt werden. Beispielsweise definiert ein C99-Compiler a __STDC_VERSION__
Makro, das die Sprachversion angibt; ein Microsoft-Compiler definiert eine _MSC_VER
Makro. (Oft beginnen diese vordefinierten Makros mit führenden Unterstrichen, da diese Namen für den Compiler reserviert sind.)
Darüber hinaus erlauben die meisten Compiler die Definition einfacher Makros als Befehlszeilenargumente. Beispielsweise könnten Sie Ihren Code über kompilieren gcc -DNDEBUG file1.c
kompilieren file.c
mit NDEBUG
zum Deaktivieren definiert assert
s.
Falls jemand dies später liest, und um einige praktische Informationen hinzuzufügen:
- In einigen Umgebungen wie atmel, vs oder iar können Sie globale #define-Direktiven definieren. Sie übergeben diese definierten Werte grundsätzlich in einem Befehlszeilenformat an den Precompiler.
- Sie können dasselbe in Batch-Befehlen oder Makefiles usw. tun.
- Arduino fügt allen Zusammenstellungen immer eine Board-Variante (normalerweise unter hardware\arduino\variants) hinzu. An diesem Punkt können Sie ein neues Board erstellen, das Ihre globalen Define-Direktiven enthält, und es so verwenden. Beispielsweise können Sie ein Mega2560(Debug)-Board aus dem ursprünglichen Mega2560 definieren, das einige Debug-Direktiven enthält. Sie fügen einen Verweis auf diese Variante in “boards.txt” hinzu, indem Sie Text kopieren, einfügen und ihn ordnungsgemäß ändern.
Am Ende des Tages müssen Sie diese globale hfile oder globale Direktive auf die eine oder andere Weise an den Compiler übergeben.
Sie sollten eine Datei1.h erstellen und Ihre Definitionen dort ablegen. Dann in file2.c
#include "file1.h"
kinderleicht 🙂
Es kommt darauf an, wo sie definiert sind.
– Nik
9. Mai 2012 um 9:01 Uhr
#define
ist eine Präprozessordirektive – sie macht nur einfache Textersetzungen zur Kompilierungszeit – nur die Kompilierungseinheit und alle#include
d-Dateien werden sehen a#define
.– PaulR
9. Mai 2012 um 9:02 Uhr