I recently added support for Pelles C to one of my projects (Hedley (http://nemequ.github.io/hedley/)), and I noticed that "calling" _Pragma multiple times on a single line causes errors. This is particularly annoying in preprocessor macros, so here's a quick test for that:
#define FOO_DLLEXPORT \
_Pragma("warn(push)") \
_Pragma("warn(disable:2016)") \
__declspec(dllexport) \
_Pragma("warn(pop)")
FOO_DLLEXPORT
void foo(void) { }
Results in
pragmas.c(7): error #1017: Syntax error in directive.
pragmas.c(7): warning #2099: Missing type specifier; assuming 'int'.
pragmas.c(7): error #2001: Syntax error: expected ')' but found 'string constant'.
pragmas.c(7): error #2001: Syntax error: expected ';' but found '_Pragma'.
pragmas.c(7): warning #2099: Missing type specifier; assuming 'int'.
pragmas.c(7): error #2001: Syntax error: expected ')' but found 'string constant'.
pragmas.c(7): warning #2117: Old-style function definition for '_Pragma'.
pragmas.c(7): warning #2016: Use of __declspec(dllexport) requires the /Ze option; ignored.
pragmas.c(7): warning #2099: Missing type specifier; assuming 'int'.
pragmas.c(7): error #2001: Syntax error: expected ')' but found 'string constant'.
pragmas.c(8): error #2001: Syntax error: expected ';' but found 'void'.
pragmas.c(8): error #2001: Syntax error: expected ';' but found '{'.
pragmas.c(8): error #2011: Declared parameter 'foo' is missing.
pragmas.c(7): error #2011: Declared parameter '_Pragma' is missing.
error #2001: Syntax error: expected '{' but found 'end of input'.
error #2001: Syntax error: expected '}' but found 'end of input'.
On the other hand, this works:
#pragma warn(push)
#pragma warn(disable:2016)
__declspec(dllexport)
#pragma warn(pop)
void foo(void) { }
As does
_Pragma("warn(push)")
_Pragma("warn(disable:2016)")
__declspec(dllexport)
_Pragma("warn(pop)")
void foo(void) { }
Have you considered that the expansion will give:
_Pragma("warn(push)") _Pragma("warn(disable:2016)") __declspec(dllexport) _Pragma("warn(pop)")
not (as probably you wished):
_Pragma("warn(push)")
_Pragma("warn(disable:2016)")
__declspec(dllexport)
_Pragma("warn(pop)")
The first is wrong, and for this reason the compiler complains.
For the same reason this shouldn't be a bug.
Yes, that's why I mentioned that the problem was with using _Pragma "multiple times on a single line", and provided an example where the _Pragmas were on multiple lines and worked. Sorry, I could have made it a bit more explicit, but yeah I agree that the problem occurs when you use multiple _Pragma operators on a single line.
I'm not sure why you think multiple pragma operators on a single line would be wrong, though. The C11 specification defines the pragma operator in ยง 6.10.9:
QuoteA unary operator expression of the form:_Pragma ( string-literal )
is processed as follows: The string literal is destringized by deleting any encoding prefix, deleting the leading and trailing double-quotes, replacing each escape sequence \" by a double-quote, and replacing each escape sequence \\ by a single backslash. The resulting sequence of characters is processed through translation phase 3 to produce preprocessing tokens that are executed as if they were the pp-tokens in a pragma directive. The original four preprocessing tokens in the unary operator expression are removed.
That seems pretty clear to me; the pragmas should be treated separately "as if they were the
pp-tokens in a pragma directive", not mapped to an actual pragma directive without a new-line to terminate it.
It does mention that the pragma directive can also be expressed with a pragma operator, but I don't see anything to indicate that the operator should be converted by the compiler to an actual directive, much less one without a terminating new-line. It's also interesting that the direction of the example is from directive to operator, not operator to directive.
I see.
For some reason the compiler stops evaluating _Pragma operator after the first one and try to parse the line remaining as code.
Seems to be a bug.
I will think about it. I don't find the C standard text about _Pragma to be very clear and helpful.
Some other compilers seem to support this, so I might add it, but we'll see...