rom1v
rom1v

Reputation: 2969

C struct: consecutive fields without padding?

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?

Upvotes: 4

Views: 472

Answers (3)

Eric Postpischil
Eric Postpischil

Reputation: 222273

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.

Upvotes: 7

Carl Norum
Carl Norum

Reputation: 224844

No, nothing is guaranteed by the standard. Your specific compiler implementation may certainly make guarantees beyond those made by the standard, though. Check your documentation for all the details.

Upvotes: 1

user2600366
user2600366

Reputation: 68

Well your definition of the struct is about 2 fields, so your compailer may not use it as an arry of 11 elements, so you will have to fill your fileds as they are decleared.

Upvotes: 0

Related Questions