The compiler may add padding for alignment requirements. Note that this applies not only to padding between the fields of a struct, but also may apply to the end of the struct (so that arrays of the structure type will have each element properly aligned).
For example:
struct foo_t {
int x;
char c;
};
Even though the c field doesn't need padding, the struct will generally have a sizeof(struct foo_t) == 8 (on a 32-bit system - rather a system with a 32-bit int type) because there will need to be 3 bytes of padding after the c field.
Note that the padding might not be required by the system (like x86 or Cortex M3) but compilers might still add it for performance reasons.
Answer from Michael Burr on Stack OverflowThe compiler may add padding for alignment requirements. Note that this applies not only to padding between the fields of a struct, but also may apply to the end of the struct (so that arrays of the structure type will have each element properly aligned).
For example:
struct foo_t {
int x;
char c;
};
Even though the c field doesn't need padding, the struct will generally have a sizeof(struct foo_t) == 8 (on a 32-bit system - rather a system with a 32-bit int type) because there will need to be 3 bytes of padding after the c field.
Note that the padding might not be required by the system (like x86 or Cortex M3) but compilers might still add it for performance reasons.
Aligning to 6 bytes is not weird, because it is aligning to addresses multiple to 4.
So basically you have 34 bytes in your structure and the next structure should be placed on the address, that is multiple to 4. The closest value after 34 is 36. And this padding area counts into the size of the structure.
sizeof single struct member in C - Stack Overflow
Calculating struct sizes
[Need explanation] casting null pointer to get sizeof() struct members
structure member offsetof() and sizeof()
Videos
Although defining the buffer size with a #define is one idiomatic way to do it, another would be to use a macro like this:
#define member_size(type, member) (sizeof( ((type *)0)->member ))
and use it like this:
typedef struct
{
float calc;
char text[255];
int used;
} Parent;
typedef struct
{
char flag;
char text[member_size(Parent, text)];
int used;
} Child;
I'm actually a bit surprised that sizeof(((type *)0)->member) is even allowed as a constant expression. Cool stuff.
I am not on my development machine right now, but I think you can do one of the following:
sizeof(((parent_t *)0)->text)
sizeof(((parent_t){0}).text)
A comment below by Lily Finley suggests an even simpler syntax:
sizeof(((parent_t){}).text)
by leaving entirely out the 0 initializing value.
Edit: I like the member_size macro Joey suggested using this technique, I think I would use that.
Hi!
I'm creating language that transpiles to C. You can introspect types my language, if the type is a struct, you can access the size of the struct. But this value is NOT calculated at compile time for my compiler ( it simply emits the sizeof operator in C).
This feels a little hacky and ideally i want the information to be available at runtime aswell. This in turn also means, i need to know how much padding the structs will have and the offsets of each member.
But how can i calculate this at compile time? Is there a specific algorithm or method a C compiler ( i use GCC to compile the C code) uses.
tl;dr how can i calculate struct sizes and padding at compile time. (With it being consistent with what GCC will decide, since i transpile to C)
In this Stackoverflow post[1] is stumbled upon a 'trick' to get the size of struct members like so: sizeof(((struct*)0)->member) which I struggle to comprehend what's happening here.
what I understand:
- sizeof calculates the size, as normal
- ->member dereferences as usual
what I don't understand:
- (struct*) 0 is a typecast (?) of a nullptr (?) to address 0 (?)
Can someone dissect this syntax and explain in detail what happens under the hood?
[1] https://stackoverflow.com/a/3553321/18918472