Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force Specific Struct Size in C

For various reasons, I have some structs I want to force to be specific sizes (in this case 64 bytes and 512 bytes). Both however, are below the somewhat below the sizes I want them to be.

Is there anyway for me to tell the compiler to set them to these specific sizes and pad with zeros, or would I be best off just declaring an array inside the struct that makes up the excess space so that it aligns on the size I want?

like image 392
themaestro Avatar asked Jan 02 '12 21:01

themaestro


People also ask

Can you use sizeof on a struct?

The sizeof for a struct is not always equal to the sum of sizeof of each individual member. This is because of the padding added by the compiler to avoid alignment issues. Padding is only added when a structure member is followed by a member with a larger size or at the end of the structure.

How the size of structure can be determined in C?

In C language, sizeof() operator is used to calculate the size of structure, variables, pointers or data types, data types could be pre-defined or user-defined. Using the sizeof() operator we can calculate the size of the structure straightforward to pass it as a parameter.

What is __ packed in C?

4.11 The __packed__ Attribute This attribute, attached to struct or union type definition, specifies that each member (other than zero-width bitfields) of the structure or union is placed to minimize the memory required. When attached to an enum definition, it indicates that the smallest integral type should be used.

How does padding work in C?

Structure Padding in C:The structure padding is automatically done by the compiler to make sure all its members are byte aligned. Here 'char' is only 1 byte but after 3 byte padding, the number starts at 4 byte boundary. For 'int' and 'double', it takes up 4 and 8 bytes respectively.


1 Answers

You can use a union.

struct mystruct_s {
    ... /* who knows how long */
};

typedef union {
    struct mystruct_s s;
    unsigned char padding[512];
} mystruct;

This will ensure the union is 512 bytes or more. Then, you can ensure that it is no more than 512 bytes using a static assertion somewhere in your code:

/* Causes a compiler error if sizeof(mystruct) != 512 */
char array[sizeof(mystruct) != 512 ? -1 : 1];

If you are using C11, there is a better way to do this. I don't know anybody who uses C11 yet. The standard was published a matter of weeks ago.

_Static_assert(sizeof(mystruct) == 512, "mystruct must be 512 bytes");

Note that the only way to pad with zeroes is to put the zeroes there manually (calloc or memset). The compiler ignores padding bytes.

like image 67
Dietrich Epp Avatar answered Sep 17 '22 18:09

Dietrich Epp