5

My very simple code shows below

#include <iostream>
#include <stdalign.h>

int main() {
    char array_char[2] = {'a', 'b'};
    float array_float[2] = {1, 2};
    std::cout << "alignof(array_char): " << alignof(array_char) << std::endl;
    std::cout << "alignof(array_float): " << alignof(array_float) << std::endl;
    std::cout << "address of array_char: " << (void *) array_char << std::endl;
    std::cout << "address of array_float: " << array_float << std::endl;
}

The output of this code is

alignof(array_char): 1

alignof(array_float): 4

address of array_char: 0x7fff5e8ec580

address of array_float: 0x7fff5e8ec570

The results of alignof operator is under expectation, but the real addresses of the two arrays are not consistent with them. No matter how many times I tried, the addresses are always 16 bytes aligned.

I'm using gcc 5.4.0 on Ubuntu 16.04 with Intel CORE i5 7th Gen CPU.

jinge
  • 785
  • 1
  • 7
  • 20
  • 4
    "*the real addresses of the two arrays are not consistent with the them*" Yes, they are. Just because something happens to be aligned to 16-byte boundaries doesn't mean that it's not also aligned to 2 or 1 byte boundaries. – Nicol Bolas Nov 27 '19 at 16:15
  • Got not 16 byte aligned [here](http://coliru.stacked-crooked.com/a/5b8143ed97d5cd83) – Jarod42 Nov 27 '19 at 16:17
  • @Jarod42 Seems gcc aligns them to 16 bytes until gcc 6.3 based on my godbolt testing. (You have gcc 9.2 there.) – walnut Nov 27 '19 at 16:21
  • This might be an answer https://stackoverflow.com/questions/41719845/memory-alignment-in-c-c – bialy Nov 27 '19 at 18:32
  • The compiler might be setting up 16-byte alignment so that it can (potentially) use SSE instructions on your data for certain operations. – Jeremy Friesner Nov 27 '19 at 19:39
  • I have another question, can you take a look? https://stackoverflow.com/questions/59098246/why-is-dynamically-allocated-memory-always-16-bytes-aligned – jinge Nov 29 '19 at 03:07

1 Answers1

3

I have found this patch.

This seems to have been a bug for x86_64 fixed in GCC 6.4.

The System V x86-64 ABI requires aggregate types (such as arrays and structs) to be aligned to at least 16 bytes if they are at least 16 bytes large. According to a comment in the ABI specification this is meant to facilitate use of SSE instructions.

GCC seem to have mistakenly applied that rule to aggregates of size 16 bits (instead of bytes) and larger.

I suggest you upgrade your compiler to a more recent GCC version.


This is however only an optimization issue, not a correctness one. There is nothing wrong with stricter alignment for the variables and (as with the mentioned SSE) overalignment may have performance benefits in some situations that outweight the cost of the wasted stack memory.

walnut
  • 21,629
  • 4
  • 23
  • 59