Message ID | 551C1A60.4080507@redhat.com |
---|---|
State | New |
Headers | show |
Florian Weimer <fweimer@redhat.com> writes: > +/* This mirrors the C11 max_align_t type provided by GCC, but it is > + also available in C99 mode. */ > +typedef struct { > + long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); > + long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); > +} libc_max_align_t; Why aren't the attributes no-ops? Andreas.
On 04/02/2015 12:01 AM, Andreas Schwab wrote: > Florian Weimer <fweimer@redhat.com> writes: > >> +/* This mirrors the C11 max_align_t type provided by GCC, but it is >> + also available in C99 mode. */ >> +typedef struct { >> + long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); >> + long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); >> +} libc_max_align_t; > > Why aren't the attributes no-ops? Quoting Joseph: “The attributes there are because some targets may give types lower alignment inside structures and unions than outside; 32-bit x86 in particular.” <https://gcc.gnu.org/ml/gcc-patches/2011-11/msg00841.html>
On Thu, Apr 02, 2015 at 12:01:34AM +0200, Andreas Schwab wrote: > Florian Weimer <fweimer@redhat.com> writes: > > > +/* This mirrors the C11 max_align_t type provided by GCC, but it is > > + also available in C99 mode. */ > > +typedef struct { > > + long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); > > + long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); > > +} libc_max_align_t; > > Why aren't the attributes no-ops? Because gcc is insane. On gcc, __alignof__ returns the "preferred alignment for optimization" that gcc would use allocating such objects individually, not the "ABI alignment" that would be used in structs, etc. Rich
> On Apr 2, 2015, at 8:40 AM, Rich Felker <dalias@libc.org> wrote: > >> On Thu, Apr 02, 2015 at 12:01:34AM +0200, Andreas Schwab wrote: >> Florian Weimer <fweimer@redhat.com> writes: >> >>> +/* This mirrors the C11 max_align_t type provided by GCC, but it is >>> + also available in C99 mode. */ >>> +typedef struct { >>> + long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); >>> + long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); >>> +} libc_max_align_t; >> >> Why aren't the attributes no-ops? > > Because gcc is insane. No. Just some abi's are insane. > > On gcc, __alignof__ returns the "preferred alignment for optimization" > that gcc would use allocating such objects individually, not the "ABI > alignment" that would be used in structs, etc. Except some abis talk about different alignment for where the field is located. > > Rich
On Thu, Apr 02, 2015 at 09:36:56AM +0800, pinskia@gmail.com wrote: > > On Apr 2, 2015, at 8:40 AM, Rich Felker <dalias@libc.org> wrote: > > > >> On Thu, Apr 02, 2015 at 12:01:34AM +0200, Andreas Schwab wrote: > >> Florian Weimer <fweimer@redhat.com> writes: > >> > >>> +/* This mirrors the C11 max_align_t type provided by GCC, but it is > >>> + also available in C99 mode. */ > >>> +typedef struct { > >>> + long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); > >>> + long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); > >>> +} libc_max_align_t; > >> > >> Why aren't the attributes no-ops? > > > > Because gcc is insane. > > No. Just some abi's are insane. I agree it was a bad ABI choice not to require alignment equal to size for all types, but at least it's consistent. On the other hand gcc is inconsistent here. The fact that Andreas had to ask why the above attributes are not no-ops should be sufficient to establish that the gcc behavior is inconsistent and confusing. > > On gcc, __alignof__ returns the "preferred alignment for optimization" > > that gcc would use allocating such objects individually, not the "ABI > > alignment" that would be used in structs, etc. > > Except some abis talk about different alignment for where the field is located. Someone can write meaningless text like that in the ABI, but it's not ABI if it's not observable. Rich
On 04/01/2015 03:01 PM, Andreas Schwab wrote: >> +typedef struct { >> >+ long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); >> >+ long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); >> >+} libc_max_align_t; > Why aren't the attributes no-ops? I wondered the same thing and reread the relevant sections of the C11 committee draft of Apri 12, 2011. It's a subtle point. max_align_t is not defined to be a type whose alignment is equal to the maximum of the alignments of all the standard types. Instead, it is defined to be a type whose alignment "is as great as is supported by the implementation in all contexts", which is not necessarily the same thing. As there doesn't seem to be any portable way to define max_align_t on a pre-C11 compiler (defining a union whose members include all standard types doesn't seem to suffice), I suppose GCC uses those attributes as a nonportable way to do the job. If so, glibc might as well be compatible with GCC.
Rich Felker <dalias@libc.org> writes:
> gcc behavior is inconsistent and confusing.
gcc just implements the ABI.
Andreas.
Florian Weimer <fweimer@redhat.com> writes: > On 04/02/2015 12:01 AM, Andreas Schwab wrote: >> Florian Weimer <fweimer@redhat.com> writes: >> >>> +/* This mirrors the C11 max_align_t type provided by GCC, but it is >>> + also available in C99 mode. */ >>> +typedef struct { >>> + long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); >>> + long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); >>> +} libc_max_align_t; >> >> Why aren't the attributes no-ops? > > Quoting Joseph: > > “The attributes there are because some targets may give types lower > alignment inside structures and unions than outside; 32-bit x86 in > particular.” This should probably be added to the comment. Andreas.
On Thu, Apr 02, 2015 at 09:33:45AM +0200, Andreas Schwab wrote: > Rich Felker <dalias@libc.org> writes: > > > gcc behavior is inconsistent and confusing. > > gcc just implements the ABI. No it doesn't. It uses "alignment of X" for two radically different things. This even resulted in a bug where they chose the wrong one initially for implementing C11 _Alignof; early gcc versions return the wrong value for it. Rich
From a521ad17ef640ff077eccd997defb4779d7040c3 Mon Sep 17 00:00:00 2001 From: Florian Weimer <fweimer@redhat.com> Date: Wed, 1 Apr 2015 18:14:50 +0200 Subject: [PATCH] Define libc_max_align_t for internal use --- ChangeLog | 4 ++++ include/libc-internal.h | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3e8df42..cc4daeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2015-04-01 Florian Weimer <fweimer@redhat.com> + + * include/libc-internal.h (libc_max_align_t): Define. + 2015-03-31 H.J. Lu <hongjiu.lu@intel.com> [BZ #18185] diff --git a/include/libc-internal.h b/include/libc-internal.h index bca59a4..9ddf409 100644 --- a/include/libc-internal.h +++ b/include/libc-internal.h @@ -107,4 +107,11 @@ extern void __init_misc (int, char **, char **); #define DIAG_IGNORE_NEEDS_COMMENT(version, option) \ _Pragma (_DIAG_STR (GCC diagnostic ignored option)) +/* This mirrors the C11 max_align_t type provided by GCC, but it is + also available in C99 mode. */ +typedef struct { + long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); + long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); +} libc_max_align_t; + #endif /* _LIBC_INTERNAL */ -- 2.1.0