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

Reply via email to