https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93239
Bug ID: 93239 Summary: Enhancement: allow unevaluated statement expressions at filescope Product: gcc Version: 7.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pskocik at gmail dot com Target Milestone: --- I've noticed gcc seems to syntactically disallow statement expressions at filescope even in contexts where they wouldn't be evaluated such as: 1) inside sizeof/__typeof/_Alignof 2) inside _Generic branches that aren't taken I'm currently trying to use 2) to implement some generic numerical macros that evaluate to an integer constant expression iff their arguments are integer constant expressions and at the same time don't double-evaluate their arguments (if those aren't integer constant expressions). A simple example would be: #define SQ(X) _Generic(0?(void*)((X)*0):(int*)0, \ int*: /*isconstexpr(X)==1*/ (X)*(X), \ void *: /*isconstexpr(X)==0*/ (__extension__({ __typeof(X) SQ = (X); SQ *= (X); })) ) Interestingly this works on tinycc (a much more primitive compiler) where it can be used in filescope to give enum values, array sizes, or bit-field widths or inside static asserts at filescope, but on gcc/clang, all of these must be inside a function. Of course, this can worked around by using an (inline) function for each integer type and a second _Generic in the non-constexpr branch of the macro that enumerates the helper functions, but that seems like a rather bloated workaround necessitated only by what seems to be an unnecessary restriction in the compiler.