Actual: $ cat test.cc int main() { return _Pragma("message \"hello\"") 1234; } $ ~/gcc482prefix/bin/gcc -c test.cc -Wall test.cc: In function ‘int main()’: test.cc:2:1: error: ‘#pragma’ is not allowed here return _Pragma("message \"my warning\"") 1234; ^ test.cc:2:44: error: expected ‘;’ before numeric constant return _Pragma("message \"my warning\"") 1234; ^ test.cc:2:49: warning: statement has no effect [-Wunused-value] return _Pragma("message \"my warning\"") 1234; ^ Expected (which is what clang does, and what MSVS does with ` __pragma(message...`): Display the message instead. (clang's output: $ ../../../chrome/src/third_party/llvm-build/Release+Asserts/ bin/clang -c test.cc -Wall test.cc:2:10: warning: my warning [-W#pragma-messages] return _Pragma("message \"my warning\"") 1234; ^ <scratch space>:2:2: note: expanded from here message "my warning" ^ 1 warning generated. ) A silly workaround is to use _Pragma("message_workaround...), then gcc will warn like so: test.cc:2:10: warning: unknown pragma ignored [-Wunknown-pragmas] return _Pragma("message_workaround \"my warning\"") 1234; ^ It'd be nice if _Pragma(message...) could be used directly, instead of having to rely on -Wunknown-pragmas for this functionality. (The usecase we have for this in Chromium is that we want to make the compiler print a diagnostic every time some symbols are used, so we define the symbols as #define MY_SYMBOL _Pragma("message \"foo\"") SYMBOL This works fine in clang and MSVC, but for gcc we have to use a dummy pragma and rely on -Wunknown-pragmas.)
Use deprecated attribute instead?
That only works on declarations, not in an expression, right? (We do have a workaround that works with gcc. But "pragma message" matches the semantics of what we want to do, and it works with MSVC and clang, so it'd be nice if it worked in gcc too.)
We want to do similar things in GLib in order to warn in the middle of arbitrary expressions or statements expanded from macros (essentially: support for deprecated macros).
Is this forbidden by the standard? The Clang and MSVC are fine with such pragma usage. It really complicates warning suppression. int main() { return #pragma GCC diagnostic push 42; } <source>: In function 'int main()': <source>:4:9: error: '#pragma' is not allowed here 4 | #pragma GCC diagnostic push | ^~~ <source>:4:12: error: expected ';' before numeric constant 4 | #pragma GCC diagnostic push | ^ | ; 5 | 42; | ~~ https://godbolt.org/z/mT1h0Z
Those pragmas are all extensions, so the standard doesn't cover them.
> Those pragmas are all extensions, so the standard doesn't cover them. There was a Clang bug report recently with a pretty much same code I had posted previously and Clang developers said that it is ill-formed with a reference to the C11 standard https://bugs.llvm.org/show_bug.cgi?id=41514#c1