On 1/7/19 9:07 AM, Dr. David Alan Gilbert wrote: >>>> Then use that macro to make MIN/MAX only evaluate their argument >>>> once; this uses type promotion (by adding to 0) to work around >>>> the fact that typeof(bitfield) won't compile. However, we are >>>> unable to work around gcc refusing to compile ({}) in a constant >>>> context, even when only used in the dead branch of a >>>> __builtin_choose_expr(),
>> Because it doesn't work - gcc treats ({}) as a syntax error inside >> constant expressions, even in dead code (although 'info gcc' said that >> might change in the future, we can't wait for that change). I also >> tried it as documented here: >> https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg00715.html >> hence my mention in the commit message. > > Ah, I didn't understand the context in your message; you say 'even in > the dead branch of a __builtin_choose_expr()' but the following works > for me (on f29 and rhel7): > > #include <stdio.h> > > # define QEMU_TYPEOF(a) typeof(a) > > #define DMIN(a,b) __builtin_choose_expr( \ > __builtin_constant_p(a) && __builtin_constant_p(b), \ > (a) < (b) ? (a) : (b), \ > ({ \ > QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > _a < _b ? _a : _b; \ > })) > > > int main(int argc, char *argv[]) > { > int anarray[DMIN(5, 10)]; Not a constant context. As written, you have declared a variable-length array, determined at runtime (even if the array is not actually variable-length because you always provide the same length). Hoist the declaration anarray outside of main() to see the difference. Or try: struct foo { int bar : DMIN(5, 10); }; for another example of a constant context (again, outside of a function). -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
signature.asc
Description: OpenPGP digital signature