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.

Reply via email to