Per C11 6.10.3.4/3, _Pragma operators are handled during rescan of an expanded macro body. Therefore, this should work: #define true \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \ true \ _Pragma("clang diagnostic pop") #define CAT2(x,y) x##y #define CAT(x,y) CAT2(x,y) int untrue = 0; int x = CAT(un, true); ... because the pragma should take effect during the rescan of the expansion of 'true', and per 6.10.9/1 the tokens should be removed before we perform the token paste. This should give 'const char *p = "xyzzy";' and no warning. #define foo _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") xyzzy #define str(x) #x #define STR(x) str(x) const char *p = STR(foo); int n() { int k; return k; } Clang gets both of these wrong.
I'm reasonably confident (as confirmed by discussion on the WG14 mailing list) that this is a wording bug in the C Standard. Paraphrasing sc22wg14 discussion, the intent is that a pragma unary operator is processed into some internal form of a #pragma directive when it's encountered (as if it were a macro), and that directive is executed if it reaches the end of phase 4 of translation.