简体   繁体   中英

How does padding of structs inside unions work?

I have the following:

#include <stdio.h>

typedef union u_data
{
        struct
        {
                int a;
                int b;
                int c;
        };
                int elem[3];
}       my_data;

int     main(void)
{
        my_data data;

        data.a = 3;
        data.b = 5;
        data.c = -3;
        printf("%d, %d, %d\n", data.elem[0], data.elem[1], data.elem[2]);
}

and it works as I expected with output: 3, 5, -3

however I understand that structs can have padding in them so does that mean that the elements in the struct might not always align with the array?

  • First of all, there is a special rule "common initial sequence" for unions in C, C11 6.5.2.3:

    One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible.

    This rule does not apply here though, since your case is a struct and an array. Had it been two structs, the rule would have applied.

  • Indeed a struct may have padding, so you are not guaranteed to get the correct output if the array is aligned differently than the struct. This is implementation-defined behavior.

  • Writing to the struct and reading from the array is fine and well-defined in C (unlike C++), C11 6.5.2.3/3, given that the two types are compatible. The struct can only be compatible with the array if there are no padding bytes.

  • "Strict aliasing" does not apply here.

Summary: this is implementation-defined behavior. You may rely on a certain behavior on a certain system, if the compiler guarantees it. The code will not be portable.

You cannot expect a , b , and c to be aligned with the elem array due to padding, as you correctly point out.

Any code that relies on the contrary is not portable C.

Padding may be introduced between struct 's members to enforce the individual alignment requirements of the members.


and it works as I expected

It looks that in your case, the alignment requirements of the members are already fulfilled, and therefore padding is not being introduced, which results in the array mapping perfectly the struct .

does that mean that the elements in the struct might not always align with the array?

No, since padding may be introduced between the members of the struct .

does that mean that the elements in the struct might not always align with the array?

No .

Your code invokes Undefined Behavior.

The array elem is not obligated to be aligned (due to padding) to the fields of the struct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM