In C Programming language and I use 32 bit system, I have a struct and this开发者_运维技巧 struct size is multiple of four. But I look at Linker Map file and size is multiple of eight Example
typedef struct _str
{
U64 var1,
U32 var2
} STR;
Size of this struct is 16. But
typedef struct _str
{
U32 var1,
U32 var2,
U32 var3
} STR2;
Size of STR2 is 12. I am working on 32 bit ARM microcontroller. I dont know why
The first structure is padded in order to get it aligned on a U64 boundary: it is equivalent to
struct STR
{
U64 var1;
U32 var2;
U8 pad[4]; /* sizeof(U64) - sizeof(U32) */
};
So when used in an array of struct STR [], each U64 is well aligned regarding to ABI requirements.
Have a look at Procedure Call Standard for ARM Architecture , 4.1 Fundamental Data Types .
The size of a structure is defined as a multiple of the alignment of a member with the largest alignment requirement. It looks like the alignment requirement of U64 is 8 bytes even in 32-bit mode on your platform.
The following code:
#include <stdio.h>
#include <stdint.h>
int main() { printf("alignof(uint64_t) is %zu\n", __alignof(uint64_t)); }
Produces the same output when compiled in both 32-bit and 64-bit mode on Linux x86_64:
alignof(uint64_t) is 8
Padding.
Suppose you have
typedef struct _str
{
U64 var1,
U32 var2
} STR;
STR s[2];
Your architecture may demand that s[0].var1
and s[1].var1
lie on the natural alignment for U64
, at 8-byte boundaries. Since C does not put padding between array elements, the padding goes inside the structure.
On the other hand,
typedef struct _str
{
U32 var1,
U32 var2,
U32 var3
} STR2;
STR2 s2[2];
Only a 4-byte alignment is required here.
A bit of background, to help you reason about such issues.
Since the primitive memory operations are generally specified in multiples of 8, compiler engineers decide on padding schemes for in-memory data-structures.
If a memory retrieval operation (memory -> bus -> cpu) is going to be 16-bit (on a hypothetical computer) chunks and you put 3*8-bit types in your struct, the compiler designer might as well pad it up to a 32-bit struct since 2,16-bit memory, retrieval operations are going to take place to pull your struct into the CPU-cache for CPU operations.
Ofcourse you can tell the compiler not to do this in exception circumstances, such as designing a on-disk or network protocol, where you might want to be space concious.
In the real world such issues are more elaborate, but the decisions stem from what the best choices are for general-purpose efficient use of your hardware :D
精彩评论