All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: Eric Blake <eblake@redhat.com>
Cc: qemu-devel@nongnu.org, dirty.ice.hu@gmail.com, f4bug@amsat.org,
	Gerd Hoffmann <kraxel@redhat.com>,
	Peter Crosthwaite <crosthwaite.peter@gmail.com>,
	Richard Henderson <rth@twiddle.net>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Juan Quintela <quintela@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v2] osdep: Make MIN/MAX evaluate arguments only once
Date: Mon, 7 Jan 2019 15:07:38 +0000	[thread overview]
Message-ID: <20190107150737.GB2442@work-vm> (raw)
In-Reply-To: <96a72fff-a7ab-ca0f-2d1b-5efdc0a9868e@redhat.com>

* Eric Blake (eblake@redhat.com) wrote:
> On 1/7/19 3:49 AM, Dr. David Alan Gilbert wrote:
> > * Eric Blake (eblake@redhat.com) wrote:
> >> Add the macro QEMU_TYPEOF() to access __auto_type in new enough
> >> compilers, while falling back to typeof on older compilers (the
> >> fallback doesn't handle variable length arrays, but we don't use
> >> those; it also expands to more text).
> >>
> >> 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(),
> 
> 
> >> +#undef MIN
> >> +#define MIN(a, b)                            \
> >> +    ({                                       \
> >> +        QEMU_TYPEOF((a) + 0) _a = (a) + 0;   \
> >> +        QEMU_TYPEOF((b) + 0) _b = (b) + 0;   \
> >> +        _a < _b ? _a : _b;                   \
> >> +    })
> >> +#define MIN_CONST(a, b)                                         \
> >> +    __builtin_choose_expr(                                      \
> >> +        __builtin_constant_p(a) && __builtin_constant_p(b),     \
> >> +        (a) < (b) ? (a) : (b),                                  \
> >> +        __builtin_unreachable())
> > 
> > Why do these need to be separate macros? Can't you just put the 
> > non-constant code in what you have as the 'builtin_unreachable' side of
> > the choose_expr:
> > 
> > #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;                   \
> >     }))
> 
> 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)];
    int a=5;
    int b=6;
    fprintf(stderr, "sizeof(anarray)=%zd DMIN(a,b)=%d\n", sizeof(anarray), DMIN(a++,b++));
    fprintf(stderr, "a=%d b=%d\n", a,b);
}

Dave

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



--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

  reply	other threads:[~2019-01-07 15:07 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-06  1:38 [Qemu-devel] [PATCH v2] osdep: Make MIN/MAX evaluate arguments only once Eric Blake
2019-01-06  8:32 ` Richard Henderson
2019-01-07 14:22   ` Eric Blake
2019-01-07  9:49 ` Dr. David Alan Gilbert
2019-01-07 14:24   ` Eric Blake
2019-01-07 15:07     ` Dr. David Alan Gilbert [this message]
2019-01-07 16:16       ` Eric Blake
2019-01-07 16:24         ` Dr. David Alan Gilbert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190107150737.GB2442@work-vm \
    --to=dgilbert@redhat.com \
    --cc=crosthwaite.peter@gmail.com \
    --cc=dirty.ice.hu@gmail.com \
    --cc=eblake@redhat.com \
    --cc=f4bug@amsat.org \
    --cc=kraxel@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.