C: Sind #define-Direktiven global?

Lesezeit: 4 Minuten

Ich bin etwas verwirrt von #define Aussagen. In Bibliotheken scheinen sie ein Kommunikationsmittel zwischen verschiedenen Dateien zu sein, mit vielen #ifdefs und #ifndefs.

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?

  • 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 #included-Dateien werden sehen a #define.

    – PaulR

    9. Mai 2012 um 9:02 Uhr


#defines 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.

  • Was meinst du mit “Einheit kompilieren”? Wie kann ich haben file1.c und file.2 in derselben Kompiliereinheit?

    – Zufallsblau

    9. Mai 2012 um 9:09 Uhr

  • Nein, sie werden separat zusammengestellt. und Henne miteinander verbunden. Kennen Sie den C-Build-Prozess?

    – MByD

    9. Mai 2012 um 9:12 Uhr

  • So file1.c und file2.c kann nie in der gleichen Kompiliereinheit sein?

    – Zufallsblau

    9. Mai 2012 um 10:00 Uhr

  • grundsätzlich – nein. Wenn Sie ein Makro gemeinsam nutzen möchten, fügen Sie es in eine Header-Datei ein und fügen Sie diesen Header in beide Dateien ein.

    – MByD

    9. Mai 2012 um 10:02 Uhr

  • @Randomblue: Stellen Sie sich eine “Kompiliereinheit” als “ac-Datei und alle darin enthaltenen Header und alle darin enthaltenen Header usw. usw. vor, bis keine Header mehr vorhanden sind”. Dies ist ein “Stück”, das der Compiler kompiliert. Nachdem der Compiler jede c-Datei separat kompiliert hat, verknüpft er diese Ausgaben miteinander.

    – Muhende Ente

    25. April 2017 um 21:44 Uhr

Benutzeravatar von jamesdlin
jamesdlin

#defined-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 #includes 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 #ifdefs, 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 asserts.

  • Thx für hilfreiche Infos

    Benutzer5066707

    25. April 2017 um 21:02 Uhr

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 🙂

1432690cookie-checkC: Sind #define-Direktiven global?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy