Domanda

I was wondering what does the standard say about how the following structure will be aligned and allocated:

struct A {
   uint8_t b[16];
};

To what extend can I expect that A will be of size 16 bytes, aligned on 16 byte boundary in an array (and size of A[n] equal to 16*n, e.g. no padding) and the address of A will be the first element of b?

And just to narrow the scope a bit, the platforms I am concerned with are x86/x64, ARM M, R, A and A50.

EDIT: A clarification - by "alignment" I mean how will the compiler align the objects in an array on the stack, e.g. will each next element be 16 bytes away, naturally I do not expect malloc to be aligned on anything but the platform default boundary.

EDIT 2: After reading on an answer, I feel inclined to ask, to what extend can I expect platform-specific explicit alignment intrinsics to work?

È stato utile?

Soluzione

The size of the struct will be at least 16. It will be 16 in normal C implementations, but I do not see that the C standard requires this, absent extenuating circumstances such as special requests from the user. E.g., if the user uses GCC’s extensions to specify that the struct must have an alignment of 32 bytes, then the struct would have to be padded to 32 bytes.

The struct cannot be expected to have an alignment requirement of 16. None of its members have an alignment requirement greater than 1, and the C standard does not require that a struct have any greater alignment requirement than its members. I do not see that the C standard requires a structure not to have a greater alignment requirement than the minimum needed to satisfy the requirements of its members, so it might be possible that a C implementation could give the struct an alignment of 16. I am unaware of C implementations that do so absent a special request from the user.

Technically, a pointer to the struct cannot be the same as a pointer to the first element of b, because the former is a pointer to a struct and the latter is a pointer to char. However, when the pointer to the struct is converted to a pointer to a uint8_t [16], it will be the same as (will compare equal to) the address of b.

In every C implementation I am familiar with, when either a pointer to the struct or a pointer to the array is further converted to a pointer to uint8_t, it will be the same as (will compare equal to) a pointer to the first element of b. However, I do not see that the C standard guarantees this. Certainly there is no padding at the start of the struct or the array, so we know the “address” of the struct is the same as the “address” of the array and the “address” of the first element, but that is not the same as a guarantee that converting pointers of different types produces the proper value.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top