0

Is there ever a time when the _Alignof returns a different value that sizeof? For example, every one that I've tried yields the same value:

printf("%zu %zu\n", _Alignof(int), sizeof (int));
printf("%zu %zu\n", _Alignof(char), sizeof (char));

4 4
1 1

Are these two values ever different (other than with an array)?

carl.hiass
  • 1,526
  • 1
  • 6
  • 26
  • 3
    C++ duplicate: [What's the difference between sizeof and alignof?](https://stackoverflow.com/questions/11386946/whats-the-difference-between-sizeof-and-alignof) – Brian61354270 Feb 26 '21 at 00:25
  • 1
    Try it with a struct with a few differently-sized members. – Shawn Feb 26 '21 at 00:48

4 Answers4

4

For struct foo { int i; char c};, many C implementations produce eight for sizeof(struct foo) and four for _Alignof(struct foo) because int is four bytes big and has an alignment requirement of four bytes. This is because the structure must have four-byte alignment to satisfy the int alignment, and that requires adding three bytes of padding, so the structure size is four bytes for the int, one for the char, and three for the padding.

Another possibility is that long double is 16 bytes in size but only requires eight-byte alignment. It might be 16 bytes because that much data is needed for it, but the hardware might have only an eight-byte bus, so only eight-byte alignment is required to be able to efficiently load the parts of any object.

Similarly, any machine will generally have some strictest alignment require x bytes because its bus is x bytes wide or its processor has a largest general word size of x, so the hardware can only process things in chunks of x bytes at a time. Then any objects larger than x bytes must be made out of multiple words and implemented using multiple instructions. For such objects, there is no need for alignment stricter than x bytes. For example, an eight-byte integer might be made out of two four-byte words with four-byte alignment, or, on older machines, a four-byte integer might be made out of two-byte words with two-byte alignment.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
2

Are these two values ever different (other than with an array)?

Example difference, most likely found with a large type.

printf("%zu %zu\n", sizeof(_Complex long double), _Alignof(_Complex long double));

Output (implementation dependent)

32 16
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 1
    Indeed, the size and alignment of a complex number **must** be different; C 2018 6.2.5 13 requires a `complex foo` have the same representation and alignment requirement as a `foo [2]`, so the alignment is at most `sizeof(foo)` (else element 1 could not be aligned if element 0 were aligned), but the size is twice that. – Eric Postpischil Feb 26 '21 at 11:29
  • @EricPostpischil Interesting: not only different, but exactly 2x, as you say. – chux - Reinstate Monica Feb 26 '21 at 14:53
  • Not necessarily exactly two times the alignment; a `double` could be eight bytes with an alignment requirement of four bytes, so a `complex` double would be 16 with four. – Eric Postpischil Feb 26 '21 at 15:01
  • @EricPostpischil Good point. At _least_ 2x then. – chux - Reinstate Monica Feb 26 '21 at 15:36
1

For a primitive type, a typical example would be long long int on a 32-bit platform. It's a 64-bit type, so 8 bytes, but made up of two 32-bit words that have to be loaded and stored individually, so there is no need for any greater alignment than 4 bytes.

Try on godbolt

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
1

Trivial case where they always must be different:

  • sizeof(char[N]) == N
  • _Alignof(char[N]) == 1.
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711