Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C struct: consecutive fields without padding?

Tags:

c

padding

struct

any_t is any type (int, struct something, …).

Consider this structure:

struct my_struct {
    any_t val,
    any_t array[10]
}

If I define a variable v:

struct my_struct v;

Is it safe to use &v.val as an array of 11 any_t items?

any_t *p = &v.val;
f(p[0]);
f(p[5]);
f(p[10]);

Is it guaranteed no padding will be added between val and array?

like image 546
rom1v Avatar asked Feb 16 '23 20:02

rom1v


1 Answers

From the C standard alone, it is not safe to use &v.val as an array of 11 any_t for these reasons:

  • The C standard permits unnamed internal padding in a struct: C 2011 (N1570) 6.7.2.1 15, “There may be unnamed padding within a structure object, but not at its beginning.” It would be unusual for a C implementation to insert padding between val and array, because alignment requirements would not require it, but it is permitted and it is conceivably beneficial in certain circumstances, such as causing array to be better aligned for performance (rather than necessity).
  • Even if there were a guarantee that the spacing of val and the array elements were the same as an array of 11 any_t, there is no guarantee that pointer arithmetic works. C 2011 (N1570) 6.5.6 8 defines pointer arithmetic (including array indexing), and it only requires that arithmetic work within an array (including one notional element at the end). Some C implementations use base-and-offset addressing. In such cases, a base address for val might fail to support offsets that extend into array.
  • Even if a C implementation uses simple flat addressing, its optimizer is permitted to make deductions based on the C standard. The optimizer can, in theory, see that a pointer is derived from the address of val and therefore cannot (in accordance with the C standard) be used to address anything in array. E.g., if you did any_t *p = &v.val; p[i] = 3; v.array[j] = 4;, the optimizer may treat the assignments to v.array[j] and p[i] as independent and perform them in any order, even though you may have set i and j so that they would point to the same element.
like image 149
Eric Postpischil Avatar answered Feb 27 '23 08:02

Eric Postpischil