开发者

During C macro expansion, is there a special case for macros that would expand to "/*"?

开发者 https://www.devze.com 2023-01-24 14:13 出处:网络
Here\'s a relevant example. It\'s obviously not valid C, but I\'m just dealing with the preprocessor here, so the code doesn\'t actually have to compile.

Here's a relevant example. It's obviously not valid C, but I'm just dealing with the preprocessor here, so the code doesn't actually have to compile.

#define IDENTITY(x) x
#define PREPEND_ASTERISK(x) *x
#define PREPEND_SLASH(x) /x

IDENTITY(literal)
PREPEND_ASTERISK(literal)
PREPEND_SLASH(literal)
IDENTITY(*pointer)
PREPEND_ASTERISK(*pointer)
PREPEND_SLASH(*pointer)

Running gcc's preprocessor on it:

gcc -std=c99 -E macrotest.c
开发者_Go百科

This yields:

(...)

literal
*literal
/literal
*pointer
**pointer
/ *pointer

Please note the extra space in the last line.

This looks like a feature to prevent macros from expanding to "/*" to me, which I'm sure is well-intentioned. But at a glance, I couldn't find anything pertaining to this behaviour in the C99 standard. Then again, I'm inexperienced at C. Can someone shed some light on this? Where is this specified? I would guess that a compiler adhering to C99 should not just insert extra spaces during macro expansion just because it would probably prevent programming mistakes.


The source code is already tokenized before being processed by CPP.

So what you have is a / and a * token that will not be combined implicitly to a /* "token" ( since /* is not really a preprocessor token I put it in "").

If you use -E to output preprocessed source CPP needs to insert a space in order to avoid /* being read by a subsequent compiler pass.

The same feature prevents from two e.g. + signs from different macros being combined into a ++ token on output.

The only way to really paste two preprocessor tokens together is with the ## operator:

#define P(x,y) x##y

...

P(foo,bar)   

results in the token foobar

P(+,+)

results in the token ++, but

P(/,*)       

is not valid since /* is not a valid preprocessor token.


The behavior of the pre-processor is standardized. In the summary at http://en.wikipedia.org/wiki/C_preprocessor , the results you are observing are the effect of:

"3: Tokenization - The preprocessor breaks the result into preprocessing tokens and whitespace. It replaces comments with whitespace".

This takes place before:

"4: Macro Expansion and Directive Handling".

0

精彩评论

暂无评论...
验证码 换一张
取 消