On Tue, Feb 12, 2019 at 06:19:56PM +1100, Daurnimator wrote: > A project I help maintain has had a report that it fails to compile with GCC 9 > https://github.com/wahern/cqueues/issues/212#issuecomment-461693111 > > I've attached a minimal reproduction of the issue. > Trying to compile it results in: > > <source>: In function 'main': > <source>:46:15: error: lvalue required as unary '&' operand > 46 | void *x = &quietinit((struct bar){ 0, .a = 0 }); > | ^ > Compiler returned: 1
Guess you need to restructure the code somewhat, with the way these macros are used it is not possible. GCC doesn't accept _Pragma at arbitrary spots within a single expression. You could just add -Wno-override-init to the options and use the macro without pragma. Or better, don't do what the macro complains about, if I understand it right, at least in the package I was looking at, there is just 0, 0, { 0, 0 } style initialization in some macros and a macro that uses quietinit sometimes ammends it with , .a = whatever, .b = whateverelse. Those 0, 0, { 0, 0 } are useless, that is the default behavior, if the compound literal is just (struct bar){}, it will be initialized to all zeros, and (struct bar){ .a = 1 } will initialize just the designated elements. And you won't get any warnings for that (at least not those in -Wall/-Wextra). Or use those quietinit-like macros as toplevel statements only and pass to the macro also a name of the pointer you assign the address to, so in the end it will be: _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Woverride-init\"") void *x = &(struct bar){ 0, .a = 0 }; _Pragma("GCC diagnostic pop") Or use the no pragmas quietinit and add another set of macros, quietinit_start/quietinit_end or whatever, define those macros to empty on everything but GCC9+, on GCC9+ define those to the starting or ending pragmas and put those in the source around the whole statements with that, rather than just in subexpressions. Jakub