C: Are #define directives global?

#defined macros are global in that they do not follow normal C scoping rules. The textual substitution from the macro will be applied (almost) anywhere the macro name appears after its #define. (Notable exceptions are if the macro name is part of a comment or part of a string literal.)

If you define a macro in a header file, any file that #includes that header file will inherit that macro (whether desired or not), unless the file explicitly undefines it afterward with #undef.

In your example, file2.c does not know about the TEST macro. How would it know to pick up the #define from file1.c? By magic? Since macros perform textual substitution on the source code, there is no representation of them in the generated object files. file2.c therefore needs to know that substitution rule itself, and if you want that shared across multiple files, that #define needs to live in a common header file that your .c files #include.

If you're asking specifically about how many of the #ifdefs that you see in libraries work, many of them are likely checking against pre-defined macro names provided by the compilation environment. For example, a C99 compiler defines a __STDC_VERSION__ macro that specifies the language version; a Microsoft compiler defines an _MSC_VER macro. (Often these predefined macros start with leading underscores since those names are reserved for the compiler.)

Additionally, most compilers allow defining simple macros as command-line arguments. For example, you might compile your code via gcc -DNDEBUG file1.c to compile file.c with NDEBUG defined to disable asserts.


In case somebody reads this later, and to add some practical information:

  • Some environments like atmel, vs, or iar, allow you to define global #define directives. They basically pass these defined values to the precompiler in some commandline format.
  • You can do the same in batch commands or makefiles, etc.
  • Arduino always adds a board variant (usually located at hardware\arduino\variants) to all compilations. At that point you can create a new board that contains your global define directives, and use it that way. For example, you can define a mega2560(debug) board out of the original mega2560 that contains some debug directives. You will add a reference to that variant in "boards.txt", by copy pasting some text, and properly modifying it.

At the end of the day, you will have to give that global hfile or global directive to the compiler in one way or another.


#defines are not global, they are just a substitution where ever they are used (if declared in the same compile unit)

They are not globals, they are not symbols, they are irrelevant at linkage, they are only relevant at pre-compilation.

Tags:

C