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.
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?
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).
related to or dup of bug 90400 or bug 69558?
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.)