Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C: Are #define directives global?

Tags:

c

I'm somewhat confused by #define statements. In libraries, they seem to be a means of communication across different files, with lots of #ifdefs and #ifndefs.

Having said that, I now have two files file1.c and file2.c compiled together, with #define TEST 10 inside file2.c. Yet, when I use TEST inside file2.c the compiler gives the following error message:

'TEST' undeclared (first use in this function)

Are #define directives global?

like image 763
Randomblue Avatar asked May 09 '12 08:05

Randomblue


People also ask

What does %d do in C?

%d is a format specifier, used in C Language. Now a format specifier is indicated by a % (percentage symbol) before the letter describing it. In simple words, a format specifier tells us the type of data to store and print. Now, %d represents the signed decimal integer.

Why is C not A or B?

Because C comes after B The reason why the language was named “C” by its creator was that it came after B language. Back then, Bell Labs already had a programming language called “B” at their disposal.

What is the basic unit of C?

The coulomb (symbol: C) is the SI derived unit of electric charge. Under the 2019 redefinition of the SI base units, the elementary charge was assigned the exact value of 1.602176634×10−19 C, making the coulomb exactly 1/(1.602176634×10−19) elementary charges.


2 Answers

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

like image 129
MByD Avatar answered Sep 28 '22 22:09

MByD


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

like image 37
jamesdlin Avatar answered Sep 28 '22 22:09

jamesdlin