https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106767
--- Comment #3 from Alexey Izbyshev <izbyshev at ispras dot ru> --- > I can make newer one recognize _Pragma only by unquoting the string literal I've investigated this strange behavior because MSVC docs do claim that C99 _Pragma is properly supported[1]. It turned out that /E (preprocess) MSVC option is semi-broken and its output can't be trusted. When it's specified, ill-formed _Pragma with arguments that are tokens instead of a string literal appears to behave like simple #pragma: > type test.c #define X 1 _Pragma(push_macro("X")) #undef X #define X 2 _Pragma(pop_macro("X")) int x = X; > cl /E /std:c11 test.c Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test.c #line 1 "test.c" int x = 1 ; And correct _Pragma with a string literal is only expanded to MSVC-internal __pragma, without actually "executing" it, so X is expanded incorrectly below: > type test.c #define X 1 _Pragma("push_macro(\"X\")") #undef X #define X 2 _Pragma("pop_macro(\"X\")") int x = X; > cl /E /std:c11 test.c Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test.c #line 1 "test.c" __pragma(push_macro("X")) __pragma(pop_macro("X")) int x = 2 ; However, without /E it works as expected: ill-formed _Pragma is a syntax error, and proper _Pragma is processed, e.g. with the previous example X is expanded to 1: >cl /c /Facon /std:c11 test.c Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test.c ; Listing generated by Microsoft (R) Optimizing Compiler Version 19.28.29910.0 include listing.inc INCLUDELIB LIBCMT INCLUDELIB OLDNAMES PUBLIC x _DATA SEGMENT x DD 01H _DATA ENDS END Nothing of the above changes the fact that macro recursion is detected properly by MSVC, so Clang and MSVC behave the same way in this regard. [1] https://docs.microsoft.com/en-us/cpp/preprocessor/pragma-directives-and-the-pragma-keyword?view=msvc-170