简体   繁体   中英

C Are arrays in structs aligned?

struct {
    uint8_t foo;
    uint8_t bar;
    uint8_t baz;
    uint8_t foos[252];
    uint8_t somethingOrOther;
} A;

struct {
    uint8_t foo;
    uint8_t bar;
    uint8_t baz;
    uint8_t somethingOrOther;
    uint8_t foos[252];
} B;

Does it matter that I've put foos on byte 3 in the first example, vs on byte 4 in B?

Does an array in C have to start aligned?

Is the size of this struct 256 bytes exactly?

Given that the data type is uint8_t (equivalent to unsigned char ), there is no need for padding in the structure, regardless of how it is ordered. So, you can reasonably assume in this case that every compiler will make that structure into 256 bytes, regardless of the order of the elements.

If there were data elements of different sizes, then you might well get padding added and the size of the structure might vary depending on the order of the elements.

As the good book says (C11 section 6.7.2.1 paragraph 14):

Each non-bit-field member of a structure or union object is aligned in an implementation- defined manner appropriate to its type... There may be unnamed padding within a structure object

You didn't "put foos on byte 3" - apart from the fact that the first element is always on byte 0, you have no real control over what byte an element will be put on. The compiler can give each field a full machine word or more if it thinks that will provide the most efficient accesses. If so, it will allocate "padding" bytes in between - unused space.

Note that this only applies to structs; arrays themselves do not add any padding bytes (if they did, the pointer arithmetic/indexing rule wouldn't work), so you can be sure that the size of foos itself is exactly the declared size, and know the exact alignment of each numbered element.

No, it doesn't matter.

Pretty much every compiler out there will align struct fields to a natural boundary appropriate for the target architecture, by inserting hidden "padding bytes" between fields where necessary.

Specifically, since you're using only uint8_t , there will be no padding bytes inserted - every field already falls on a naturally-aligned boundary. (Everything is a multiple of one.)

Both of the struct s you've shown are exactly 256 bytes in size. You can confirm this like so:

int main(void)
{
    printf("sizeof(struct A)=%zu \n", sizeof(struct A));
    printf("sizeof(struct B)=%zu \n", sizeof(struct B));
}

You can prevent this padding from being added by "packing" the structure:

Do note that doing this on a structure with unaligned members can have a serious impact on the performance of your program.

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