Reputation: 29985
If I do this:
#define F a
F/
It expands to a/
godbolt
If I do this:
#define F /
F/
It expands to / /
with a space in between goodbolt
But if I convert it to a string, and print it, it doesn't add any spaces goodbolt:
#include <stdio.h>
#define STR_IMPL(x) #x
#define STR(x) STR_IMPL(x)
#define F /
int main() {
puts(STR(F/));
}
Why is there a space in between, but only some of the time? Is it allowed to add more spaces in other cases?
Upvotes: 4
Views: 1058
Reputation: 141628
The language specification is like this, at a high level:
There is no specification of any intermediate plain-text representation between the steps . What you are seeing in the "preprocessor output" is entirely at the whim of the vendor, so long as the final result of the whole translation process behaves as specified.
Analysis of the example with #define F /
and STR(F/)
:
First note that #define F /
followed by newline means that F
is replaced by the two tokens w /
(where I am using w to mean a whitespace token).
The sequence of preprocessing tokens for STR(F/)
after tokenization is:
STR
, (
, F
, /
, )
After the first round of macro substitution the tokens are:
STR_IMPL
, (
, w, /
, /
, )
After the second round, the tokens are:
"//"
.The definition of the #
preprocessing operator includes that leading whitespace is removed. So the token sequence w, /
, /
becomes "//"
, not " //"
.
There was never any space between the F/
or the two slashes at any point.
Upvotes: 3
Reputation: 72044
Macros work on the token level. Spaces are added when printing the result in string form to disambiguate.
F/
is two tokens, F
and /
. After macro expansion, it still needs to be two tokens, /
and /
. But if you print them next to each other, it becomes //
, which is just one token (a comment). So there needs to be a space in-between.
Long story short: yes, macro expansion can add spaces, because spaces don't matter at the level macros operate at.
Upvotes: 5