In implementing my own C11 compiler, I'm trying to figure out how exactly to handle the _Pragma
keyword/operator. C11 §6.10.9 describes _Pragma
as being an operator, so it seems possible to redefine it with macros, i.e. #define _Pragma(x) SOME_OTHER_MACRO(x)
. Further, the statement #undef _Pragma
should have no effect (assuming no prior #define
of _Pragma
). This is similar to how keywords can be #define
d, such as the old VC++ hack #define for if (0) ; else for
. However, because the _Pragma
operator is evaluated during translation phase 3, the same phase as executing preprocessor directives, it's not clear whether this is an exception; the standard doesn't mention whether its undefined behavior to use _Pragma
as a macro name.
I did some testing with GCC using the following code:
#define PRAGMA _Pragma
PRAGMA("message \"hi\"")
_Pragma ("message \"sup\"")
#undef PRAGMA
#undef _Pragma
//#define _Pragma(x)
_Pragma("message \"hello\"")
Compiling with gcc -std=c11 -pedantic -Wall -Wextra -c
outputs:
tmp.c:2:1: note: #pragma message: hi
PRAGMA("message \"hi\"")
^
tmp.c:4:1: note: #pragma message: sup
_Pragma ("message \"sup\"")
^
tmp.c:8:8: warning: undefining "_Pragma" [enabled by default]
#undef _Pragma
^
tmp.c:10:9: error: expected declaration specifiers or ‘...’ before string constant
_Pragma("message \"hello\"")
^
If I add the line #undef _Alignof
, GCC doesn't complain about it.
This suggests that GCC implements _Pragma
through a macro (via the warning message), and that undefining it results in a compile error. If I uncomment #define _Pragma(x)
, the error goes away (as the string literal disappears).
So, my questions are:
_Pragma
as just a macro, and not implement it as an operator?_Pragma
is supposed to be an operator, is it undefined behavior to define _Pragma
as a macro?_Pragma
evaluation and other preprocessor directives? Or do they have the same "precedence" (i.e. they're evaluated in-order)?Again, looking through the C11 standard does not mention anything about _Pragma
other than it's an operator that can be used for #pragma
directives.
There is no need for a special rule that would forbid _Pragma
to be a macro name. Having a leading underscore and capital letter, it is among the reserved identifiers that you are not supposed to use, anyhow. Using reserved identifiers leads to undefined behavior of your program, a compiler may do anything.
An implementation may implement it as a macro, but that should be transparent to you, as long as you use it correctly, that is as long as you don't mess around with it. The only important thing that an implementation must guarantee is that the "destringization" and "tokeninzation" of the argument to the _Pragma
is done as if in phase 3 (which is difficult if it is "only" a macro) and that the resulting #pragma
directive is processed in phase 4.
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