Reputation: 5300
I want to define the following ordinary looking macro:
#define MY_ENUM enum MyEnum{ \
myVal0, \ //Describes this situation
myVal2 \ //Describes that situation
}
To my surprise this doesn't work due to error: stray ‘\’ in program
. Even some whitespace after the backslash results in warning: backslash and newline separated by space
. As this answer points out, the backslash must be the last character on the line. This answer points out that line splicing occurs before comments are processed. The reason why this order was chosen makes absolutely no sense to me; the only reason I can imagine this could be done is to allow multiline comments like the following:
//This is a comment which \
follows in the next line
Which looks extremely dangerous as such a thing could just eat up whatever code is on the next line when attempted. The reverse order, i.e replace each comment with single whitespace before splicing lines sounds like a much more sensible choice to me. Can someone explain why this choice was made?
I can work around my original problem with the following:
#define MY_ENUM enum MyEnum{ \
myVal1, /*Describes this situation*/ \
myVal2 /*Describes that situation*/ \
}
My purpose when doing this awkward enum macro definition is that this macro must be shared between c++ (where it absolutely must be a class member due to Qt) and c. Defining a macro such as this looks like the only solution to me but the above workaround looks ugly and I absolutely don't want to leave enums uncommented. Am I approaching this problem wrong?
Upvotes: 7
Views: 1333
Reputation: 1
The problem is that the C preprocessor just adds another line ending character when the \
is hit and continued.
Within //
comments you can't do that. The \
character isn't accepted to continue the comment (it's supposed to appear as a single line anyway).
The solution is—as you found out yourself—to use the /* */
comment style.
Upvotes: 5
Reputation: 37914
To understand this phenomenon, you may to refer into the C standard (I believe that C++ is similar to C in that manner). In particular it's in translation phases section (C11 draft §5.1.1.2).
The preprocessor is obligated to behave just like as the phases are executed in the top-down order (i.e. step 3 is executed after step 2 has finished completely etc.).
Basically, the //
and /* ... */
comments are recognized in phase three, that is performed after the trailing \
handling (i.e. phase two), meaning that it is agnostic to them. In other words, it treats them just like an ordinary source text with no special meaning.
Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice.
The source file is decomposed into preprocessing tokens7) and sequences of white-space characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment.Each comment is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined.
Upvotes: 1