1. #define NUM 10 2. #define FOO NUM 3. #undef NUM 4. #define NUM 20 5. 6. FOO
When I only run the preprocessor, the output file contains 20.
However, from what I understand, the preprocessor simply does text replacement. So this is what I think is happening (which is obviously wrong but idky):
So I think the output should be 10 instead of 20. Can anything explain where it went wrong?
You can't. Macros are expanded by the Preprocessor, which happens even before the code is compiled. It is a purely textual replacement.
Macro substitution is a mechanism that provides a string substitution. It can be achieved through "#deifne". It is used to replace the first part with the second part of the macro definition, before the execution of the program. The first object may be a function type or an object.
In your case 8 bytes.
The text replacement is done where the macro is used, not where you wrote the #define
. At the point you use FOO
, it replaces FOO
with NUM
and NUM
is currently defined to be 20
.
In the interests of collecting all the relevant specifications from the standards, I extracted this information from a comment thread, and added C++ section numbers, based on draft N4527 (the normative text is identical in the two standards). The standard(s) are absolutely clear on the subject.
#define
preprocessor directives do not undergo macro replacement.
(C11 §6.10¶7; C++ §16[cpp] ¶6): The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated.
After a macro is replaced with its replacement text, the new text is rescanned. Preprocessor tokens in the replacement are expanded as macros if there is an active macro definition for the token at that point in the program.
(C11 §6.10.3¶9; C++ §16.3[cpp.replace] ¶9) A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive. The replacement list is then rescanned for more macro names as specified below.
A macro definition is active from the line following the #define
until an #undef
for the macro name, or the end of the file.
(C11 §6.10.3.5¶1; C++ §16.3.5[cpp.scope] ¶1) A macro definition lasts (independent of block structure) until a corresponding
#undef
directive is encountered or (if none is encountered) until the end of the preprocessing translation unit. Macro definitions have no significance after translation phase 4.
If we look at the program:
#define NUM 10 #define FOO NUM #undef NUM #define NUM 20 FOO
we see that the macro definition of NUM
in line 1 lasts exactly to line 3. There is no replaceable text in those lines, so the definition is never used; consequently, the program is effectively the same as:
#define FOO NUM #define NUM 20 FOO
In this program, at the third line, there is an active definition for FOO
, with replacement list NUM
, and for NUM
, with replacement list 20
. The FOO
is replaced with its replacement list, making it NUM
, and then that is once again scanned for macros, resulting in NUM
being replaced with its replacement list 20. That replacement is again rescanned, but there are no defined macros, so the end result is that the token 20
is left for processing in translation phase 5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With