• Create Account

### #ActualEctara

Posted 11 February 2013 - 09:58 AM

#define MY_STR "abc"
#define CONCAT(s) \
#define TEMP MY_STR \  // store MY_STR in TEMP_STR
#undef MY_STR \        // undefine MY_STR
#define MY_STR TEMP s  // redefine MY_STR so it contains the old value plus the new one

CONCAT(def)
printf("%s\n", MY_STR);  // should hopefully print out "abc def"


This will NOT work in C/C++. The preprocessor will evaluate the body of the macro once it is invoked for replacement, and no sooner. You also can't put preprocessor directives that alter the definitions of macros inside of a macro body in Standard C/C++. That means that first you define MY_STR to the sequence of tokens "abc", and you define CONCAT(s) to the sequence of tokens #define TEMP MY_STR #undef MY_STR #define MY_STR TEMP s. Even if you could, you would literally #define TEMP to the sequence of tokens MY_STR.

When you go to invoke TEMP, it then replaces it with MY_STR. When that is invoked, it is replaced with "abc". Next, you undefine MY_STR. The next time TEMP is used, the macro substitution stops there, because it is no longer a macro, and just leaves MY_STR, which causes an error when compiled. And lastly, #define MY_STR TEMP s will re-#define MY_STR to the sequence of tokens TEMP (tokens represented by s). As we saw just a moment ago, TEMP is defined to contain the token MY_STR, not its value, so MY_STR is #define'd to MY_STR (tokens represented by s). And this will throw an error if it didn't halt the compilation already.

The preprocessor does not copy values of macros! It just adds the macro's name to the list of tokens that the macro represents, and it will expand and replace it when it is used.

For C: (§6.10.3.4/3: "The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one ...").

For C++: (§16.4.3/3: "The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one...").

### #3Ectara

Posted 11 February 2013 - 09:51 AM

#define MY_STR "abc"
#define CONCAT(s) \
#define TEMP MY_STR \  // store MY_STR in TEMP_STR
#undef MY_STR \        // undefine MY_STR
#define MY_STR TEMP s  // redefine MY_STR so it contains the old value plus the new one

CONCAT(def)
printf("%s\n", MY_STR);  // should hopefully print out "abc def"


This will NOT work in C/C++. The preprocessor will evaluate the body of the macro once it is invoked for replacement, and no sooner. You also can't put preprocessor directives that alter the definitions of macros inside of a macro body in Standard C/C++. That means that first you define MY_STR to the sequence of tokens "abc", and you define CONCAT(s) to the sequence of tokens #define TEMP MY_STR #undef MY_STR #define MY_STR TEMP s. Even if you could, you would literally #define TEMP to the sequence of tokens MY_STR.

When you go to invoke TEMP, it then replaces it with MY_STR. When that is invoked, it is replaced with "abc". Next, you undefine MY_STR. The next time TEMP is used, the macro substitution stops there, because it is no longer a macro, and just leaves MY_STR, which causes an error when compiled. And lastly, #define MY_STR TEMP s will re-#define MY_STR to the sequence of tokens TEMP (tokens represented by s). As we saw just a moment ago, TEMP is defined to contain the token MY_STR, not its value, so MY_STR is #define'd to MY_STR (tokens represented by s). And this will throw an error if it didn't halt the compilation already.

The preprocessor does not copy values of macros! It just adds the macro's name to the list of tokens that the macro represents, and it will expand and replace it when it is used.

For C: (§6.10.3.4/3: "The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one ...").

For C++: (§16.3.1, footnote 147: "Since, by macro-replacement time, all character literals and string literals are preprocessing tokens, not sequences possibly containing identifierlike subsequences (see 2.1.1.2, translation phases), they are never scanned for macro names or parameters."),

and (§16.4.3/3: "The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one...").

### #2Ectara

Posted 11 February 2013 - 09:40 AM

#define MY_STR "abc"
#define CONCAT(s) \
#define TEMP MY_STR \  // store MY_STR in TEMP_STR
#undef MY_STR \        // undefine MY_STR
#define MY_STR TEMP s  // redefine MY_STR so it contains the old value plus the new one

CONCAT(def)
printf("%s\n", MY_STR);  // should hopefully print out "abc def"


This will NOT work in C/C++. The preprocessor will evaluate the body of the macro once it is invoked for replacement, and no sooner. You also can't put preprocessor directives that alter the definitions of macros inside of a macro body in Standard C/C++. That means that first you define MY_STR to the sequence of tokens "abc", and you define CONCAT(s) to the sequence of tokens #define TEMP MY_STR #undef MY_STR #define MY_STR TEMP s. Even if you could, you would literally #define TEMP to the sequence of tokens MY_STR.

When you go to invoke TEMP, it then replaces it with MY_STR. When that is invoked, it is replaced with "abc". Next, you undefine MY_STR. The next time TEMP is used, the macro substitution stops there, because it is no longer a macro, and just leaves MY_STR, which causes an error when compiled. And lastly, #define MY_STR TEMP s will re-#define MY_STR to the sequence of tokens TEMP (tokens represented by s). As we saw just a moment ago, TEMP is defined to contain the token MY_STR, not its value, so MY_STR is #define'd to MY_STR (tokens represented by s). And this will throw an error if it didn't halt the compilation already.

The preprocessor does not copy values of macros! It just adds the macro's name to the list of tokens that the macro represents, and it will expand and replace it when it is used.

### #1Ectara

Posted 11 February 2013 - 09:37 AM

#define MY_STR "abc"
#define CONCAT(s) \
#define TEMP MY_STR \  // store MY_STR in TEMP_STR
#undef MY_STR \        // undefine MY_STR
#define MY_STR TEMP s  // redefine MY_STR so it contains the old value plus the new one

CONCAT(def)
printf("%s\n", MY_STR);  // should hopefully print out "abc def"


This will NOT work in C/C++. The preprocessor will evaluate the body of the macro once it is invoked for replacement. That means that first you define MY_STR to the sequence of tokens "abc", and you define CONCAT(s) to the sequence of tokens #define TEMP MY_STR #undef MY_STR #define MY_STR TEMP s. You can't put preprocessor directives that alter the definitions of macros inside of a macro body in Standard C/C++. Even if you could, you would literally #define TEMP to the sequence of tokens MY_STR.

When you go to invoke TEMP, it then replaces it with MY_STR. When that is invoked, it is replaced with "abc". Next, you undefine MY_STR. The macro substitution stops there, because it is no longer a macro, and just leaves MY_STR, which causes an error. And lastly, #define MY_STR TEMP s will re-#define MY_STR to the sequence of tokens TEMP (tokens represented by s). As we saw just a moment ago, TEMP is defined to contain the token MY_STR, not its value, so MY_STR is #define'd to MY_STR (tokens represented by s). And this will throw an error if it didn't halt the compilation already.

The preprocessor does not copy values of macros! It just adds the macro's name to the list of tokens that the macro represents, and it will expand and replace it when it is used.

PARTNERS