This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/52023] _Alignof (double) yields wrong value on x86


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023

bruno at clisp dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bruno at clisp dot org

--- Comment #2 from bruno at clisp dot org 2012-01-27 21:01:11 UTC ---
I can reproduce the bug with gcc version 4.7-20120121 (snapshot) for x86.
Test program:

===================================================
#include <stdint.h>
#include <stdio.h>
#include <stddef.h>
#include <stdalign.h>
int main ()
{
  typedef struct { char slot1; int64_t slot2; } int64_t_helper;
  typedef struct { char slot1; double slot2; } double_helper;
  printf ("%d %d %d\n",
          alignof (int64_t),
          offsetof (int64_t_helper, slot2),
          alignof (int64_t) == offsetof (int64_t_helper, slot2));
  printf ("%d %d %d\n",
          alignof (double),
          offsetof (double_helper, slot2),
          alignof (double) == offsetof (double_helper, slot2));
}
===================================================
Actual output:
8 4 0
8 4 0
Expected output:
4 4 1
4 4 1

(In reply to comment #1)
> I don't think this is a bug, the alignment requirements in a struct can be
> different from outside of a struct.

You could argue like this for __alignof__ which is a GCC invention.

But since ISO C11 and since <stdalign.h> is included, we have to look what
ISO C11 says about it. Citing the latest draft of it (n1570.pdf):

6.5.3.4.(3)
  "The _Alignof operator yields the alignment requirement of its operand type.
The
   operand is not evaluated and the result is an integer constant. When applied
to
   an array type, the result is the alignment requirement of the element type."

3.2 alignment
  "requirement that objects of a particular type be located on storage
boundaries
   with addresses that are particular multiples of a byte address"

3.15 object
  "region of data storage in the execution environment, the contents of which
   can represent values"

As a consequence of these definitions, the alignment of a type inside a struct
could be a multiple of _Alignof(type), but the alignment of a type inside a
struct
cannot be less than _Alignof(type).

In other words, if
  alignof (double) == 8
then every 'double' object in memory must be on an address that is a multiple
of 8.
Then objects inside the 'double_helper' type must also always be at addresses
that
are a multiple of 8. Which by the rules for structs means that
  alignof (double_helper)
and
  offsetof (double_helper, slot2)
must both be multiples of 8.

More about structs in ISO C11:

6.7.2.1.(6)
  "a structure is a type consisting of a sequence of members, whose
   storage is allocated in an ordered sequence"

6.7.2.1.(14)
  "Each non-bit-field member of a structure or union object is aligned in an
   implementation-defined manner appropriate to its type."

Note the last part of the last sentence: "appropriate to its type". The
implementation does not have the freedom to ignore the type's alignment
when deciding about offsetof of a member in a struct.

Please reopen this bug. (I cannot find how to do this witin the bugzilla GUI.)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]