NO

Author Topic: Multiple _Pragmas cause errors  (Read 128 times)

Offline nemequ

  • Member
  • *
  • Posts: 1
Multiple _Pragmas cause errors
« on: April 12, 2019, 08:09:00 pm »
I recently added support for Pelles C to one of my projects (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:

Code: [Select]
#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:

Code: [Select]
#pragma warn(push)
#pragma warn(disable:2016)
__declspec(dllexport)
#pragma warn(pop)
void foo(void) { }

As does

Code: [Select]
_Pragma("warn(push)")
_Pragma("warn(disable:2016)")
__declspec(dllexport)
_Pragma("warn(pop)")
void foo(void) { }
« Last Edit: April 12, 2019, 08:20:06 pm by nemequ »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1692
Re: Multiple _Pragmas cause errors
« Reply #1 on: April 13, 2019, 04:35:50 pm »
Have you considered that the expansion will give:
Code: [Select]
_Pragma("warn(push)") _Pragma("warn(disable:2016)") __declspec(dllexport) _Pragma("warn(pop)")

not (as probably you wished):
Code: [Select]
_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.

Offline nemequ

  • Member
  • *
  • Posts: 1
Re: Multiple _Pragmas cause errors
« Reply #2 on: April 14, 2019, 07:44:33 am »
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:

Quote
A unary operator expression of the form:
Code: [Select]
_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.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1692
Re: Multiple _Pragmas cause errors
« Reply #3 on: April 14, 2019, 05:19:55 pm »
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.

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 1974
    • http://www.smorgasbordet.com
Re: Multiple _Pragmas cause errors
« Reply #4 on: April 21, 2019, 09:36:24 pm »
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...
/Pelle