Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

#pragma are considered statements

346 views
Skip to first unread message

dS...@arcor.de

unread,
Sep 22, 2014, 3:45:09 AM9/22/14
to
The program

int main()
{
int result = 1;
if (result < 0)
#pragma GCC diagnostic ignored "-Wunused-result"
return result;
return 0;
}

returns 1 if translated by recent GCC compilers. I perceived this as erroneous and submitted a bug report, but that was rejected as invalid with the remark "#pragma are considered statements." Is the declaration of such syntactic
significance of a preprocessing directive compatible with the C standard?

Richard Bos

unread,
Sep 22, 2014, 4:11:56 AM9/22/14
to
#pragma directives cause implementation-defined behaviour. In fact, the
Standard quite directly says: "The behavior might cause translation to
fail or cause the translator or the resulting program to behave in a
non-conforming manner". So GCC is allowed to do this.

Whether it's _desirable_ is another matter. But it's quite legal.

Richard

Tim Rentsch

unread,
Sep 22, 2014, 12:53:14 PM9/22/14
to
An implementation is allowed to treat the #pragma as a statement,
but if the implementation's documentation doesn't say that will
happen I would say it's a bug.

Of course, even if it's a bug, leaving out the {}'s in situations
like this is asking for trouble. But I think it may be worth
pointing out to the implementors that "implementation-defined"
doesn't mean that they can do whatever they want to without also
providing the appropriate (and accurate) documentation.

Richard Bos

unread,
Sep 22, 2014, 4:12:52 PM9/22/14
to
Tim Rentsch <t...@alumni.caltech.edu> wrote:

> ral...@xs4all.nl (Richard Bos) writes:
> > "dS...@arcor.de" <dS...@arcor.de> wrote:
> >
> >> The program
> >>
> >> int main()
> >> {
> >> int result = 1;
> >> if (result < 0)
> >> #pragma GCC diagnostic ignored "-Wunused-result"
> >> return result;
> >> return 0;
> >> }
> >>
> >> returns 1 if translated by recent GCC compilers. I perceived
> >> this as erroneous and submitted a bug report, but that was
> >> rejected as invalid with the remark "#pragma are considered
> >> statements." Is the declaration of such syntactic significance
> >> of a preprocessing directive compatible with the C standard?
> >
> > #pragma directives cause implementation-defined behaviour. In
> > fact, the Standard quite directly says: "The behavior might cause
> > translation to fail or cause the translator or the resulting
> > program to behave in a non-conforming manner". So GCC is allowed
> > to do this.
>
> An implementation is allowed to treat the #pragma as a statement,
> but if the implementation's documentation doesn't say that will
> happen I would say it's a bug.

I agree, but I haven't delved into the GCC documentation, let alone that
specific version's. So I can't claim that it _doesn't_ say so.

> Of course, even if it's a bug, leaving out the {}'s in situations
> like this is asking for trouble.

I very much agree with that.

Richard

Kaz Kylheku

unread,
Sep 22, 2014, 4:30:28 PM9/22/14
to
On 2014-09-22, dS...@arcor.de <dS...@arcor.de> wrote:
> The program
>
> int main()
> {
> int result = 1;
> if (result < 0)
> #pragma GCC diagnostic ignored "-Wunused-result"
> return result;

Putting a #pragma between an "if (...)" and its associated statement
is moronic.

You deserve to be burned.

Derek M. Jones

unread,
Sep 22, 2014, 6:57:54 PM9/22/14
to

> returns 1 if translated by recent GCC compilers. I perceived this as erroneous and submitted a bug report, but that was rejected as invalid with the remark "#pragma are considered statements." Is the declaration of such syntactic
> significance of a preprocessing directive compatible with the C standard?

Interesting reply from the gcc maintainer.

Does the status of this #pragma as a statement mean that it can only
occur within a function definition?

The version of gcc I am using, 4.7.2, produces the 'expected' behavior.
So I cannot easily check what you are seeing.

Sentence 132 http://c0x.coding-guidelines.com/5.1.1.2.html
makes life difficult for implementors of this behavior.

What does gcc do? Does it cause #pragma to effectively
expand to a ; (semicolon), in which case this kind of
#pragma can occur anywhere a declaration can occur.

Presumably the following generates a syntax error???

int foo(
#pragma GCC diagnostic ignored "-Wunused-result"
);

A failure to document this implementation-defined behavior could
be treated as a bug in the documentation.

dS...@arcor.de

unread,
Sep 23, 2014, 4:30:05 AM9/23/14
to
23. September 2014 00:57:54 UTC+2, Derek M. Jones:
> > returns 1 if translated by recent GCC compilers. I perceived this as erroneous and submitted a bug report, but that was rejected as invalid with the remark "#pragma are considered statements." Is the declaration of such syntactic significance of a preprocessing directive compatible with the C standard?
>
> Interesting reply from the gcc maintainer.
>
> Does the status of this #pragma as a statement mean that it can only
> occur within a function definition?

That's a good question. In fact, it is also accepted outside of a function.

> The version of gcc I am using, 4.7.2, produces the 'expected' behavior.

Interesting ... gcc 4.7.4 has the new, unexpected behaviour.

> Sentence 132 http://c0x.coding-guidelines.com/5.1.1.2.html
> makes life difficult for implementors of this behavior.

That's nicely put.

> What does gcc do? Does it cause #pragma to effectively
> expand to a ; (semicolon), in which case this kind of
> #pragma can occur anywhere a declaration can occur.

No, the code I posted is already the preprocessed output (generated by the option -save-temps as well as -E), I only omitted file and line information and re-indented. So, the sentence 132 "All preprocessing directives are then deleted" has not been followed. Could the argument that the compiler must act as if the directive were deleted be brought forward?

> Presumably the following generates a syntax error???
>
> int foo(
> #pragma GCC diagnostic ignored "-Wunused-result"
> );

That's true.

error: expected declaration specifiers or '...' before '#pragma'

> A failure to document this implementation-defined behavior could
> be treated as a bug in the documentation.

Perhaps I can succeed in at least this.

James Kuyper

unread,
Sep 23, 2014, 9:15:04 AM9/23/14
to
On 09/23/2014 04:30 AM, dS...@arcor.de wrote:
> 23. September 2014 00:57:54 UTC+2, Derek M. Jones:
>>> returns 1 if translated by recent GCC compilers. I perceived this as erroneous and submitted a bug report, but that was rejected as invalid with the remark "#pragma are considered statements." Is the declaration of such syntactic significance of a preprocessing directive compatible with the C standard?
>>
>> Interesting reply from the gcc maintainer.
>>
>> Does the status of this #pragma as a statement mean that it can only
>> occur within a function definition?
>
> That's a good question. In fact, it is also accepted outside of a function.
>
>> The version of gcc I am using, 4.7.2, produces the 'expected' behavior.
>
> Interesting ... gcc 4.7.4 has the new, unexpected behaviour.
>
>> Sentence 132 http://c0x.coding-guidelines.com/5.1.1.2.html
>> makes life difficult for implementors of this behavior.
>
> That's nicely put.
>
>> What does gcc do? Does it cause #pragma to effectively
>> expand to a ; (semicolon), in which case this kind of
>> #pragma can occur anywhere a declaration can occur.
>
> No, the code I posted is already the preprocessed output (generated
> by the option -save-temps as well as -E), I only omitted file and line
> information and re-indented. So, the sentence 132 "All preprocessing
> directives are then deleted" has not been followed. Could the argument
> that the compiler must act as if the directive were deleted be brought
> forward?

It is normally required that pre-processing directives be deleted at the
end of translation phase 4 (5.1.1.2p4), long before statements are
parsed as such during translation phase 7 (5.1.1.2p7). However, the
implementation-defined consequences of ordinary #pragma directives
(6.10.6p1) are effectively unlimited - they can override anything that
should normally happen during or after translation phase 4 (since they
are not recognized as preprocessing directives until phase 4).

The only exception is for #pragma directives where the first
preprocessing token after the #pragmas is STDC (6.10.6p2). Those have
only standard-defined behavior, and therefore are not free to override
5.1.1.2. Do you see the same behavior with -std=c99 and

#pragma STDC FP_CONTRACT ON

if so, that's non-conforming behavior.


--
James Kuyper

Phil Carmody

unread,
Sep 24, 2014, 4:38:59 AM9/24/14
to
Whilst I agree with everyone else that you should not expect the #pragma
to leave the code in a state you'd recognise once its executed and deleted,
I also think that saying "#pragmas are considered statements" is between
meaningless, misleading, and just plain wrong. "statement"s are a syntactical
concept that make no sense, or at least have no relevance, at the relevant
preprocessing time.

What does the output of the preprocessor look like in this failing case?

If the pragma gets replaced with (void)var; for ever (function-)block-scoped
variable, which whilst unlikely is within gcc's remit, then that would be
your problem.

What happens if you use one of the STDC pragmas, as James insightfully
mentions, in a context like this:

void foo(int x)
{
if (printf("%i\n",x))
#pragma STDC //...whatever
}

If that #pragma is not "considered a statement", and you want to piss off
the GCC guys, then file a bug, citing their previous comment. You shouldn't
lie to your compiler, your compiler shouldn't lie to you, but also compiler
maintainers shouldn't lie to their users.

Phil
--
The best part of re-inventing the wheel is that you get to pick how
many sides the new one has. -- egcagrac0 on SoylentNews

dS...@arcor.de

unread,
Sep 24, 2014, 7:00:09 AM9/24/14
to
23. September 2014 15:15:04 UTC+2, James Kuyper:
> It is normally required that pre-processing directives be deleted at the
> end of translation phase 4 (5.1.1.2p4), long before statements are
> parsed as such during translation phase 7 (5.1.1.2p7). However, the
> implementation-defined consequences of ordinary #pragma directives
> (6.10.6p1) are effectively unlimited - they can override anything that
> should normally happen during or after translation phase 4 (since they
> are not recognized as preprocessing directives until phase 4).

Thanks for pointing to 6.10.6p1 - the phrase "cause the translator or the resulting program to behave in a non-conforming manner" makes it apparent that there is no "legal" basis against this behaviour.

> The only exception is for #pragma directives where the first
> preprocessing token after the #pragmas is STDC (6.10.6p2). Those have
> only standard-defined behavior, and therefore are not free to override
> 5.1.1.2. Do you see the same behavior with -std=c99 and
>
> #pragma STDC FP_CONTRACT ON

No, (un?)fortunately with #pragma STDC instead the program's behaviour is as one would expect the same as without any #pragma, so, it's conforming.

dS...@arcor.de

unread,
Sep 24, 2014, 7:21:25 AM9/24/14
to
24. September 2014 10:38:59 UTC+2, Phil Carmody:
> Whilst I agree with everyone else that you should not expect the #pragma
> to leave the code in a state you'd recognise once its executed and deleted,
> I also think that saying "#pragmas are considered statements" is between
> meaningless, misleading, and just plain wrong. "statement"s are a syntactical
> concept that make no sense, or at least have no relevance, at the relevant
> preprocessing time.
>
> What does the output of the preprocessor look like in this failing case?

The code I posted is already the preprocessed output, I only omitted file and line information and re-indented.

> If the pragma gets replaced with (void)var; for ever (function-)block-scoped
> variable, which whilst unlikely is within gcc's remit, then that would be
> your problem.

The pragma line didn't get replaced.

> What happens if you use one of the STDC pragmas, as James insightfully
> mentions, in a context like this:
>
> void foo(int x)
> {
> if (printf("%i\n",x))
> #pragma STDC //...whatever
> }

error: expected expression before '}' token

> If that #pragma is not "considered a statement", and you want to piss off
> the GCC guys, then file a bug, citing their previous comment. You shouldn't
> lie to your compiler, your compiler shouldn't lie to you, but also compiler
> maintainers shouldn't lie to their users.

Well, I don't exactly want to piss off anyone. :-)
Perhaps I could find gentle words to express the inconsistency.

Wojtek Lerch

unread,
Sep 24, 2014, 9:17:10 AM9/24/14
to
On 24-Sep-14 7:21 AM, dS...@arcor.de wrote:
> The code I posted is already the preprocessed output, I only omitted file and line information and re-indented.

I assume that by "preprocessed output" you mean the output of GCC's
preprocessor; but does their documentation claim that that output
precisely matches what the program turns into after translation phase 4,
as defined in the standard? I suspect that it doesn't, given the fact
that it contained file and line information you had to omit (I assume
you meant #file and #line directives, right?)?

dS...@arcor.de

unread,
Sep 29, 2014, 3:39:05 AM9/29/14
to
24. September 2014 15:17:10 UTC+2, Wojtek Lerch:
> I assume that by "preprocessed output" you mean the output of GCC's
> preprocessor; but does their documentation claim that that output
> precisely matches what the program turns into after translation phase 4,
> as defined in the standard? I suspect that it doesn't, given the fact
> that it contained file and line information you had to omit (I assume
> you meant #file and #line directives, right?)?

As far as I can see, the GCC's documentation makes no mention or claim about translation phase 4, just as you suspect. The unmodified preprocessor output is:

# 1 "bug.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "bug.c"
0 new messages