Message ID | 20180810171102.16451-1-alex.bennee@linaro.org |
---|---|
Headers | show |
Series | tweaks for QEMU's C standard | expand |
On Fri, Aug 10, 2018 at 06:10:58PM +0100, Alex Bennée wrote: > Hi, > > While I was reviewing Richard's SVE series I found Travis choking on > some perfectly valid c99. It turns out that Travis default image is > old enough that gcc defaults to -std=gnu89 hence the problem. However > switching to c99 isn't enough as we use GNUisms and even gnu99 still > trips up on qemu-secomp. > > Of course we could just jump to C11 already? We've always required GCC or a compatible compiler (CLang is only viable alternative option really). We use a number of GCC extensions to the C standard and I don't see a compelling reason to stop using them. From that POV I think we do *NOT* need to care about official C standards (c89, c99, c11, etc), only the GNU C standards (gnu89, gnu99, gnu11, etc). > This is an RFC because this could descend into a C standards > bike-shedding exercise but I thought I'd at least put it out there on > a Friday afternoon ;-) I did some archeology to inform our plans... The default GCC C standards across various versions are: 8.2.1: gnu17 7.3.1: gnu11 6.4.1: gnu11 5.3.1: gnu11 4.9.1: gnu89 4.4.7: gnu89 Interesting to note that no version of GCC ever defaulted to gnu99. It was not fully implemented initially and by the time the standard was fully implemented, gnu11 was already good enough to be the default. So GCC jumped straight from gnu89 as default to gnu11 as default. Across the various distros we aim to support we have: RHEL-7: 4.8.5 Debian (Stretch): 6.3.0 Debian (Jessie): 4.9.2 OpenBSD (Ports): 4.9.4 FreeBSD (Ports): 8.2.0 OpenSUSE Leap 15: 7.3.1 SLE12-SP2: Ubuntu (Xenial): 5.4.0 macOS (Homebrew): 8.2.0 IOW plenty of our plaforms are still on 4.x which defaults to gnu89. In GCC 4.x, gnu99 is said to be incomplete (but usable) and gnu11 are said to be incomplete and experimental (ie don't use it). The lowest common denominator supported by all our platforms is thus gnu89. If we don't mind that gnu99 is not fully complete in 4.x, we could use that standard. We definitely can't use gnu11 any time soon. Given that many modern platforms default to gnu11, I think we should set an explicit -std=gnu89, or -std=gnu99, because otherwise we risk accidentally introducing code that relies on gnu11 features. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
On Mon, Aug 13, 2018 at 10:07:05AM +0100, Daniel P. Berrangé wrote: > On Fri, Aug 10, 2018 at 06:10:58PM +0100, Alex Bennée wrote: > > Hi, > > > > While I was reviewing Richard's SVE series I found Travis choking on > > some perfectly valid c99. It turns out that Travis default image is > > old enough that gcc defaults to -std=gnu89 hence the problem. However > > switching to c99 isn't enough as we use GNUisms and even gnu99 still > > trips up on qemu-secomp. > > > > Of course we could just jump to C11 already? > > We've always required GCC or a compatible compiler (CLang is only viable > alternative option really). We use a number of GCC extensions to the C > standard and I don't see a compelling reason to stop using them. > > From that POV I think we do *NOT* need to care about official C standards > (c89, c99, c11, etc), only the GNU C standards (gnu89, gnu99, gnu11, etc). > > > This is an RFC because this could descend into a C standards > > bike-shedding exercise but I thought I'd at least put it out there on > > a Friday afternoon ;-) > > I did some archeology to inform our plans... > > The default GCC C standards across various versions are: > > 8.2.1: gnu17 > 7.3.1: gnu11 > 6.4.1: gnu11 > 5.3.1: gnu11 > 4.9.1: gnu89 > 4.4.7: gnu89 > > Interesting to note that no version of GCC ever defaulted to gnu99. It was > not fully implemented initially and by the time the standard was fully > implemented, gnu11 was already good enough to be the default. So GCC jumped > straight from gnu89 as default to gnu11 as default. > > Across the various distros we aim to support we have: > > RHEL-7: 4.8.5 > Debian (Stretch): 6.3.0 > Debian (Jessie): 4.9.2 > OpenBSD (Ports): 4.9.4 > FreeBSD (Ports): 8.2.0 > OpenSUSE Leap 15: 7.3.1 > SLE12-SP2: > Ubuntu (Xenial): 5.4.0 > macOS (Homebrew): 8.2.0 > > IOW plenty of our plaforms are still on 4.x which defaults to gnu89. > > In GCC 4.x, gnu99 is said to be incomplete (but usable) and gnu11 > are said to be incomplete and experimental (ie don't use it). > > The lowest common denominator supported by all our platforms is thus > gnu89. > > If we don't mind that gnu99 is not fully complete in 4.x, we could use > that standard. > > We definitely can't use gnu11 any time soon. > > Given that many modern platforms default to gnu11, I think we should > set an explicit -std=gnu89, or -std=gnu99, because otherwise we risk > accidentally introducing code that relies on gnu11 features. Also, we should ensure the min required GCC version via biuld time check of some kind. eg something like #if !(__GNUC_PREREQ(4, 4) || defined(__clang__)) # error "QEMU requires GCC >= 4.4, or CLang" #endif We can even check the C standard at build time if desired. eg I see these symbols defined for various -std=xxx args: gnu89: #undef __STDC_VERSION__ gnu99: #define __STDC_VERSION__ 199901 gnu11: #define __STDC_VERSION__ 201112L gnu17: #define __STDC_VERSION__ 201710L (See "gcc -std=XXX -dM -E - < /dev/null") Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
On 08/13/2018 11:07 AM, Daniel P. Berrangé wrote: > On Fri, Aug 10, 2018 at 06:10:58PM +0100, Alex Bennée wrote: >> Hi, >> >> While I was reviewing Richard's SVE series I found Travis choking on >> some perfectly valid c99. It turns out that Travis default image is >> old enough that gcc defaults to -std=gnu89 hence the problem. However >> switching to c99 isn't enough as we use GNUisms and even gnu99 still >> trips up on qemu-secomp. >> >> Of course we could just jump to C11 already? > > We've always required GCC or a compatible compiler (CLang is only viable > alternative option really). We use a number of GCC extensions to the C > standard and I don't see a compelling reason to stop using them. > > From that POV I think we do *NOT* need to care about official C standards > (c89, c99, c11, etc), only the GNU C standards (gnu89, gnu99, gnu11, etc). > >> This is an RFC because this could descend into a C standards >> bike-shedding exercise but I thought I'd at least put it out there on >> a Friday afternoon ;-) > > I did some archeology to inform our plans... > > The default GCC C standards across various versions are: > > 8.2.1: gnu17 > 7.3.1: gnu11 > 6.4.1: gnu11 > 5.3.1: gnu11 > 4.9.1: gnu89 > 4.4.7: gnu89 > > Interesting to note that no version of GCC ever defaulted to gnu99. It was > not fully implemented initially and by the time the standard was fully > implemented, gnu11 was already good enough to be the default. So GCC jumped > straight from gnu89 as default to gnu11 as default. > > Across the various distros we aim to support we have: > > RHEL-7: 4.8.5 > Debian (Stretch): 6.3.0 > Debian (Jessie): 4.9.2 > OpenBSD (Ports): 4.9.4 > FreeBSD (Ports): 8.2.0 > OpenSUSE Leap 15: 7.3.1 > SLE12-SP2: > Ubuntu (Xenial): 5.4.0 > macOS (Homebrew): 8.2.0 > > IOW plenty of our plaforms are still on 4.x which defaults to gnu89. Thanks for the great summary! > In GCC 4.x, gnu99 is said to be incomplete (but usable) and gnu11 > are said to be incomplete and experimental (ie don't use it). > > The lowest common denominator supported by all our platforms is thus > gnu89. > > If we don't mind that gnu99 is not fully complete in 4.x, we could use > that standard. > > We definitely can't use gnu11 any time soon. > > Given that many modern platforms default to gnu11, I think we should > set an explicit -std=gnu89, or -std=gnu99, because otherwise we risk > accidentally introducing code that relies on gnu11 features. Sounds good. What about trying -std=gnu99 first, and if we run into problems, switch back to -std=gnu89 later? Thomas
On 13 August 2018 at 10:18, Daniel P. Berrangé <berrange@redhat.com> wrote: > Also, we should ensure the min required GCC version via biuld time > check of some kind. eg something like > > #if !(__GNUC_PREREQ(4, 4) || defined(__clang__)) > # error "QEMU requires GCC >= 4.4, or CLang" > #endif Our current minimum is 4.1, I think (per commit fa54abb8c298f), though we could bump that if there's utility in doing so. Overall I think we should prefer to avoid specific gcc version checks wherever we can. clang supports a useful set of tests like __has_feature and __has_attribute; gcc supports some of these (eg __has_attribute from gcc 5). Random aside: I just stumbled across a comment in configure about a workaround for a gcc 4.6.x bug which says "We should be able to delete this at the end of 2013" :-) thanks -- PMM
Daniel P. Berrangé <berrange@redhat.com> writes: > On Mon, Aug 13, 2018 at 10:07:05AM +0100, Daniel P. Berrangé wrote: >> On Fri, Aug 10, 2018 at 06:10:58PM +0100, Alex Bennée wrote: >> > Hi, >> > >> > While I was reviewing Richard's SVE series I found Travis choking on >> > some perfectly valid c99. It turns out that Travis default image is >> > old enough that gcc defaults to -std=gnu89 hence the problem. However >> > switching to c99 isn't enough as we use GNUisms and even gnu99 still >> > trips up on qemu-secomp. >> > >> > Of course we could just jump to C11 already? >> >> We've always required GCC or a compatible compiler (CLang is only viable >> alternative option really). We use a number of GCC extensions to the C >> standard and I don't see a compelling reason to stop using them. >> >> From that POV I think we do *NOT* need to care about official C standards >> (c89, c99, c11, etc), only the GNU C standards (gnu89, gnu99, gnu11, etc). >> >> > This is an RFC because this could descend into a C standards >> > bike-shedding exercise but I thought I'd at least put it out there on >> > a Friday afternoon ;-) >> >> I did some archeology to inform our plans... >> >> The default GCC C standards across various versions are: >> >> 8.2.1: gnu17 >> 7.3.1: gnu11 >> 6.4.1: gnu11 >> 5.3.1: gnu11 >> 4.9.1: gnu89 >> 4.4.7: gnu89 >> >> Interesting to note that no version of GCC ever defaulted to gnu99. It was >> not fully implemented initially and by the time the standard was fully >> implemented, gnu11 was already good enough to be the default. So GCC jumped >> straight from gnu89 as default to gnu11 as default. >> >> Across the various distros we aim to support we have: >> >> RHEL-7: 4.8.5 >> Debian (Stretch): 6.3.0 >> Debian (Jessie): 4.9.2 >> OpenBSD (Ports): 4.9.4 >> FreeBSD (Ports): 8.2.0 >> OpenSUSE Leap 15: 7.3.1 >> SLE12-SP2: >> Ubuntu (Xenial): 5.4.0 >> macOS (Homebrew): 8.2.0 >> >> IOW plenty of our plaforms are still on 4.x which defaults to gnu89. >> >> In GCC 4.x, gnu99 is said to be incomplete (but usable) and gnu11 >> are said to be incomplete and experimental (ie don't use it). >> >> The lowest common denominator supported by all our platforms is thus >> gnu89. >> >> If we don't mind that gnu99 is not fully complete in 4.x, we could use >> that standard. Thanks for the digging. I wonder what is missing in 4.x? As far as I can tell we make heavy use of typeof() but I don't know how to audit for other GNUisms? Everything should be in a compiler.h right? I just noticed we have a C11-like generics macro in there ;-) >> >> We definitely can't use gnu11 any time soon. >> >> Given that many modern platforms default to gnu11, I think we should >> set an explicit -std=gnu89, or -std=gnu99, because otherwise we risk >> accidentally introducing code that relies on gnu11 features. > > Also, we should ensure the min required GCC version via biuld time > check of some kind. eg something like > > #if !(__GNUC_PREREQ(4, 4) || defined(__clang__)) > # error "QEMU requires GCC >= 4.4, or CLang" > #endif > > > We can even check the C standard at build time if desired. eg I see > these symbols defined for various -std=xxx args: > > gnu89: #undef __STDC_VERSION__ > gnu99: #define __STDC_VERSION__ 199901 > gnu11: #define __STDC_VERSION__ 201112L > gnu17: #define __STDC_VERSION__ 201710L > > > (See "gcc -std=XXX -dM -E - < /dev/null") > > Regards, > Daniel -- Alex Bennée
On Mon, Aug 13, 2018 at 11:25:49AM +0200, Thomas Huth wrote: > On 08/13/2018 11:07 AM, Daniel P. Berrangé wrote: > > On Fri, Aug 10, 2018 at 06:10:58PM +0100, Alex Bennée wrote: > >> Hi, > >> > >> While I was reviewing Richard's SVE series I found Travis choking on > >> some perfectly valid c99. It turns out that Travis default image is > >> old enough that gcc defaults to -std=gnu89 hence the problem. However > >> switching to c99 isn't enough as we use GNUisms and even gnu99 still > >> trips up on qemu-secomp. > >> > >> Of course we could just jump to C11 already? > > > > We've always required GCC or a compatible compiler (CLang is only viable > > alternative option really). We use a number of GCC extensions to the C > > standard and I don't see a compelling reason to stop using them. > > > > From that POV I think we do *NOT* need to care about official C standards > > (c89, c99, c11, etc), only the GNU C standards (gnu89, gnu99, gnu11, etc). > > > >> This is an RFC because this could descend into a C standards > >> bike-shedding exercise but I thought I'd at least put it out there on > >> a Friday afternoon ;-) > > > > I did some archeology to inform our plans... > > > > The default GCC C standards across various versions are: > > > > 8.2.1: gnu17 > > 7.3.1: gnu11 > > 6.4.1: gnu11 > > 5.3.1: gnu11 > > 4.9.1: gnu89 > > 4.4.7: gnu89 > > > > Interesting to note that no version of GCC ever defaulted to gnu99. It was > > not fully implemented initially and by the time the standard was fully > > implemented, gnu11 was already good enough to be the default. So GCC jumped > > straight from gnu89 as default to gnu11 as default. > > > > Across the various distros we aim to support we have: > > > > RHEL-7: 4.8.5 > > Debian (Stretch): 6.3.0 > > Debian (Jessie): 4.9.2 > > OpenBSD (Ports): 4.9.4 > > FreeBSD (Ports): 8.2.0 > > OpenSUSE Leap 15: 7.3.1 > > SLE12-SP2: > > Ubuntu (Xenial): 5.4.0 > > macOS (Homebrew): 8.2.0 > > > > IOW plenty of our plaforms are still on 4.x which defaults to gnu89. > > Thanks for the great summary! > > > In GCC 4.x, gnu99 is said to be incomplete (but usable) and gnu11 > > are said to be incomplete and experimental (ie don't use it). > > > > The lowest common denominator supported by all our platforms is thus > > gnu89. > > > > If we don't mind that gnu99 is not fully complete in 4.x, we could use > > that standard. > > > > We definitely can't use gnu11 any time soon. > > > > Given that many modern platforms default to gnu11, I think we should > > set an explicit -std=gnu89, or -std=gnu99, because otherwise we risk > > accidentally introducing code that relies on gnu11 features. > > Sounds good. What about trying -std=gnu99 first, and if we run into > problems, switch back to -std=gnu89 later? I don't have a strong opinion either way - both options would be better than what we do today by relying on the variable gcc built-in defaults. Using -std=gnu99 gives slightly weaker protection in that we might still accidentally use features which are not supported in the limitd gnu99 impl of gcc 4.x. I think that's unlikely, however, hence I don't really mind either of gnu89 or gnu99 Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|