Macros as arguments to preprocessor directives

旧街凉风 提交于 2019-12-01 22:40:42

From § 16.2-4 ("Source file inclusion") of C++ 2003 draft:

A preprocessing directive of the form

# include pp-tokens new-line 

(that does not match one of the two previous forms) is permitted. The preprocessing tokens after include in the directive are processed just as in normal text (each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens).

§ 6.10.2-4 of C99 says the same.

The "two previous forms" mentioned above are # include <h-char-sequence> and # include "q-char-sequence". The section seems too simple to summarize.

For other directives, macro expansion isn't performed on any identifier preprocessing token (note this behavior is not defined by the grammar, but by C++ § 16 / C § 6.10):

# if constant-expression new-line [group] 
# ifdef identifier new-line [group] 
# ifndef identifier new-line [group] 
# elif constant-expression new-line [group] 
# else new-line [group] 
# endif new-line 
# include pp-tokens new-line 
# define identifier replacement-list new-line 
# define identifier lparen [identifier-list] ) replacement-list new-line 
# undef identifier new-line 
# line pp-tokens new-line 
# error [pp-tokens] new-line 
# pragma [pp-tokens] new-line 
# new-line 

#line is explicitly macro-expanded by C++ § 16.4-5 / C § 6.10.4-5. Expansion for #error (C++ § 16.5 / C § 6.10.5) and #pragma (C++ § 16.6 / C § 6.10.6) isn't mentioned. C++ § 16.3-7 / C 6.10.3-8 states:

If a # preprocessing token, followed by an identifier, occurs lexically at the point at which a preprocessing directive could begin, the identifier is not subject to macro replacement.

C++ § 16.3.1 / C § 6.10.3.1-1 tells us that when the arguments to a macro function are substituted into the replacement-list, they are first macro expanded. Similarly, C++ § 16.3.4 / C § 6.10.3.4 has the preprocessor macro-expand the replacement-list after substitution.

In summary, macro expansion is done for #if, #elif, #include, #line, the arguments to a macro function and the body of a macro function when substituted. I think that's everything.

It's a very fundamental feature of the C preprocessor -- for example, a directive such as #ifdef makes zero sense except when used with an argument that's possibly a macro (if you had to know that the argument is not allowed to be a macro, what could the purpose of #ifdef possibly be?!).

I'm not sure how chapter and verse of the ISO C standard would help you -- the C++ standard, as I recall, does not change the preprocessor's operation anyway.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!