Pointer arithmetics between consecutive members of same type in a struct used to be a common practice while pointer arithmetics is only valid inside an array. In C++ it would be explicitely Undefined Behaviour because an array can only be created by a declaration or a new expression. But C language defines an array as a contiguously allocated nonempty set of objects with a particular member object type, called the element type. (n1570 draft for C11, 6.2.5 types §20). So provided we can make sure that that the members are consecutive (meaning no padding between them) it could be legal to see that as an array.
Here is a simplified example, that compiles without a warning and gives expected results at run time:
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
struct quad {
int x;
int y;
int z;
int t;
};
int main() {
// ensure members are consecutive (note 1)
static_assert(offsetof(struct quad, t) == 3 * sizeof(int),
"unexpected padding in quad struct");
struct quad q;
int *ix = &q.x;
for(int i=0; i<4; i++) {
ix[i] = i;
}
printf("Quad: %d %d %d %d\n", q.x, q.y, q.z, q.t);
return 0;
}
It does not really make sense here, but I have already seen real world example where iterating among members of a struct allows simpler code with less risk of typo.
Question:
In the above example, is the static_assert
enough to make legal the aliasing of the struct with an array?
(note 1) As a struct describes a sequentially allocated nonempty set of member objects, later members must have increasing addresses. Simply the compiler could include padding between them. So the offset of last member (here t
) if 3 times sizeof(int)
plus the total padding before it. If the offset is exactly 3 * sizeof(int)
then there is no padding in struct
The question proposed as a duplicate contains both an accepted answer that let think that it would be UB, and a +1 answer that let think that it could be legal because I could ensure that no padding could exist