qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC PATCH] osdep: Make MIN/MAX evaluate arguments only


From: Eric Blake
Subject: Re: [Qemu-devel] [RFC PATCH] osdep: Make MIN/MAX evaluate arguments only once
Date: Sat, 5 Jan 2019 08:34:26 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1

On 1/5/19 7:48 AM, Eric Blake wrote:

> I'm fine keeping the name MIN/MAX for the common use, but we'd need a
> second pair, maybe named MIN_CONST/MAX_CONST, for use in contexts that
> require a constant (there, both arguments are evaluated twice because it
> is the naive implementation, but that is harmless because both arguments
> are constant and the macro is then usable in places where the smart
> MIN/MAX are not).  I don't know if trying to use __builtin_constant_p in
> the const version would also be worthwhile.  In fact, if
> __builtin_constant_p is powerful enough, perhaps we could use it to
> force a single macro to expand to the naive version if both arguments
> are constant and the smart version otherwise.  I'll give that a shot.

Alas, even though __builtin_constant_p can let the compiler overlook
SOME cases of non-constant code (as in __builtin_constant_p(0 && foo())
returning 1), it is not powerful enough to ignore the dead branch:

$ cat foo.c
#define MIN(a, b)                                               \
    (__builtin_constant_p(a) && __builtin_constant_p(b) ?       \
     (a) < (b) ? (a) : (b) :                                    \
     ({                                                         \
         __auto_type _a = (a) + 0;                              \
         __auto_type _b = (b) + 0;                              \
         _a < _b ? _a : _b;                                     \
     }))

char x[MIN(1, 2)];

int
main(int argc, char **argv)
{
    return MIN(argc, 0);
}
$ gcc -o foo -Wall foo.c
foo.c:4:6: error: braced-group within expression allowed only inside a
function
      ({                                                         \
      ^
foo.c:10:8: note: in expansion of macro ‘MIN’
 char x[MIN(1, 2)];
        ^~~

If anyone can come up with a workaround for single-macro usage, be my
guest.  Otherwise, I'm going with the two-macro solution, with MIN/MAX
for common use, and MIN_CONST/MAX_CONST for constant-context use.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]