4

The following C program tries to stringify and then print the expansions of two object-like macros:

#include  <stdio.h>

#define FOOBAR foobar // I'll be gone soon :(
#define UNHOLY \"     // I'm in your strings

#define STR_(X) #X
#define STR(X) STR_(X)

int main() {
    printf("%s\n", STR(FOOBAR));
    printf("%s\n", STR(UNHOLY));
    return 0;
}

When compiled with GCC and Clang, the stringification of FOOBAR produces the expected results. However, UNHOLY manages to somehow retain the comment, which ends up in the string. As far as I know, comments are stripped long before the preprocessor runs, so I can only conclude that this is a lexer issue.

VC won't even compile this. It bails out with the error: escaped '"': is illegal in macro definition. Can I simply remove the comment and assume it will work as intended (i.e. second print should produce ") in compliant C compilers? Is VC broken again, or am I invoking some kind of unholy undefined behavior?

user3026691
  • 497
  • 2
  • 11
  • I am not sure about "comments are stripped long before the preprocessor runs". I always use /* */ just to avoid this case – Swanand Dec 13 '16 at 12:33
  • especially because // is officially not a comment in c before c99 – Kami Kaze Dec 13 '16 at 12:38
  • @unwind This is not dupe: This question asks *"Can I simply **remove the comment** and assume it will work as intended in compliant C compilers?"*. Linked question is strictly about comments, this is about double quote. Please reopen. – user694733 Dec 13 '16 at 12:56
  • It is C99, but the same thing happens with `/**/`. However, I didn't tag the question as C99-specific because I didn't know older standards didn't specify that comments should be stripped first like C99 does. Either way, I don't entirely understand why this question is closed. The linked question incidentally does contain an answer (one of the answers mentions something that suggests my comments aren't treated as comments because the lexer thinks they're in a string literal) but it's not the accepted answer and it's tangential to the subject of the linked question. :\ – user3026691 Dec 13 '16 at 13:03
  • In case this question doesn't get reopened: You should be aware that C standard has some caveats with character escape rules. \ and " should be escaped automatically with \, so `\"` should expand to `"\\\""` if I understood correctly. Thus `#define UNHOLY "` *should be* (assuming compilers respect that) what you are after. This is in N1570 $6.10.3.2 p2, but older standards should have similar rule. – user694733 Dec 13 '16 at 13:11
  • @user694733 Your suggestion produces the same results in GCC and Clang. VC still refuses to compile, but with a different error... To make things even weirder, if I run `gcc -E` to see the expansion, it produces what looks like a broken string (`"""`). That's why I put the escape character there in the first place... I didn't think it would compile (but it does). – user3026691 Dec 13 '16 at 13:33
  • That sounds bad. Unless there are any compiler switches to change the behaviour, I guess all 3 compilers are broken. Only solution for you maybe conditional compilation for different compilers. Might get messy with VC though. – user694733 Dec 13 '16 at 13:48
  • I this indeed is not standard conformant behavior then it should be reported to the compiler devs. @user694733 and OP – Kami Kaze Feb 20 '17 at 08:33

0 Answers0