Bug 91285 - _Pragma does not work in a useful fashion
Summary: _Pragma does not work in a useful fashion
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-07-29 12:06 UTC by Konrad Schwarz
Modified: 2022-11-28 19:19 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-01-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Konrad Schwarz 2019-07-29 12:06:50 UTC
Consider the following code:

# define        ENCLOSING_OBJECT(TYPE, MEMBER, OBJECT)\
        (sizeof (&((TYPE *) 0)->MEMBER - OBJECT),\
        (TYPE *) ((char *) OBJECT - offsetof (TYPE, MEMBER)))

What this does is find the address of an "enclosing object" given the
address of one of its members MEMBER as OBJECT.
This can be useful when interacting with
programming frameworks -- often, MEMBER is actually the first element
of the application-defined object, but this macro is generic enough
that it doesn't have to be so.

As an additional compile-time type-safety check, the macro expansion 
includes an additional clause that ensures that OBJECT is indeed of the
type of MEMBER by subtracting its address from a synthesized enclosing
objects member's address;
this subtraction is done as the argument of sizeof(), ensuring
it doesn't actually get executed at run-time.

Newer versions of GCC flag this construct with an "unused value" warning,
which can be disabled globally with
# pragma GCC diagnostic ignored "-Wunused-value".

In general however, the unused value warning is useful, so one
would like to restrict the scope of ignoring the warning to as
small an area as possible.  The GCC diagnostic pragmas allow this
to be done with the `diagnostic push' and `diagnostic pop'
sub-commands.

In C90, one would have to add # pragma directives around each use
of the macro, clearly an undesirable approach.  Hence, in C0x,
_Pragma was introduced to allow pragma directives to
result as a by-product of macro expansion.

Thus, the C0x solution would be to extend the definition of the macro
with
    _Pragma ("GCC diagnostic push")\
    _Pragma ("GCC diagnostic ignored \"-Wunused-value\"")\
    -- original macro text --\
    _Pragma ("GCC diagnostic pop")

However, GCC fails to compile this, because it can't handle
pragmas in the middle of expressions.

This makes the GCC implementation of _Pragma worthless.
Comment 1 Andrew Pinski 2019-07-29 14:40:18 UTC
Isn't it better to do:

# define        ENCLOSING_OBJECT(TYPE, MEMBER, OBJECT)\
        ((void)sizeof (&((TYPE *) 0)->MEMBER - OBJECT),\
        (TYPE *) ((char *) OBJECT - offsetof (TYPE, MEMBER)))

Instead?
Comment 2 Konrad Schwarz 2019-07-29 15:03:43 UTC
Thank you for your suggestion -- it does indeed work.

However, this is a workaround for this specific problem --
other pragmas cannot be handled in this way --
consider # pragma GCC optimize ... or # pragma align ...
or # pragma longcall (although the last two
apply to declarations).
Comment 3 Eric Gallager 2019-08-04 16:08:49 UTC
related to or dup of bug 90400 or bug 69558?
Comment 4 jsm-csl@polyomino.org.uk 2019-08-07 15:31:40 UTC
Note that all the standard C pragmas are even more restricted than GCC's 
statement-like pragmas - the standard pragmas (which aren't implemented in 
GCC) are defined by the C standard to be allowed only "either outside 
external declarations or preceding all explicit declarations and 
statements inside a compound statement".

The wider the range of contexts in which a pragma is permitted, the harder 
it is to define its semantics.  For diagnostic pragmas, note that some 
diagnostics are associated with a *range* of locations within an 
expression, leading to obvious questions about the semantics if diagnostic 
pragma state varies within that range.  (Though that could also arise when 
statement-like pragmas are used within the existing statement expression 
extension.)