According to C11 standard, an argument of a function-like macro can contain whitespace at the beginning or the end of its preprocessing token sequence. For normal replacement, this kind of spaces has no effects. For stringification, spaces should be ignored as mentioned in 6.10.3.2.2
White space before the first preprocessing token and after the last preprocessing token composing the argument is deleted.
(which I believe is also an evidence proving that arguments can have spaces around it.) And the question is, for arguments that would be concatenated by ## operator, what should compiler do about its spaces?
I tried it with VC++, which seems just ignore the spaces.
I think the compiler should perform the concatenation with whitespace. This may lead to invalid token, for example, "ABC " formed by identifier ABC and an argument with a white space as the first token. According to the standard, if an invalid token is formed in this way, the behavior is undefined.
So for what VC++ has done as mentioned before, is it the result of simply ignoring the space or the result of the undefined behavior?
Macro names must begin with a letter and use either letters or numerals. You cannot use spaces, non-alphanumeric characters, or periods. Macro names can be 80 characters maximum.
Macro Concatenation with the ## OperatorThe ## (double number sign) operator concatenates two tokens in a macro invocation (text and/or arguments) given in a macro definition. If a macro XY was defined using the following directive: #define XY(x,y) x##y.
The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.
C Preprocessor Glue: The ## Operator Like the # operator, the ## operator can be used in the replacement section of a function-like macro. Additionally, it can be used in the replacement section of an object-like macro. The ## operator combines two tokens into a single token.
which I believe is also an evidence proving that arguments can have spaces around it
No, in fact it only reinforces the standard's provision that each macro argument is a sequence of preprocessing tokens (C2011, 6.10.3/11). Whitespace in the source file separates preprocessing tokens; runs of whitespace are not preprocessing tokens themselves.
The section of the standard you cite is potentially confusing because it mixes levels -- the character sequence of the source file, to which whitespace belongs, and the preprocessing token sequence arising from the intial tokenization of the source sequence. Indeed, stringification is sensitive to whether adjacent tokens are separated by whitespace in the source character sequence, but the details of any such whitespace do not matter at all -- upon stringification, adjacent tokens that were white-space separated are separated by a single space character in the resulting string.
That does not mean that a preprocessing token can start or end with whitespace. It can't; see section 6.4 of the standard for full details. How a given implementation satisfies the specifications for stringification is necessarily implementation specific, but one way an implementation could do so would involve maintaining boolean flags for each preprocessing token describing whether that token is preceded and / or followed in the source sequence by whitespace. Such details have nothing to do with interpreting what the standard specifies for the result, however, neither for the stringification operator nor for the token pasting operator.
for arguments that would be concatenated by ## operator, what should compiler do about its spaces?
By the time the ##
operator (or the #
operator) comes into play, the compiler has already done everything it ever will (directly) do with space characters appearing in the source file, by considering them during tokenization of the source into preprocessing tokens. Macro arguments are sequences of preprocessing tokens, and only to the extent that those tokens may be string or character literals or header names may they contain whitespace. Moreover, the standard specifies:
If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a
##
preprocessing token, the parameter is replaced by the corresponding argument’s preprocessing token sequence [...]
(C2011, 6.10.3.3/2; emphasis added)
Once again, whitespace runs are not preprocessing tokens. Macro expansion and the #
and ##
operators deal with, and operate at the level of, sequences of preprocessing tokens. Whitespace is represented at this level only internally within tokens. Whitespace from the source file that is not internal to a preprocessing token is represented only indirectly and uncertainly in the preprocessing token sequence.
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