Type sizes, alignment boundaries, struct padding, and how to order members for efficiency.
Every type has an alignment requirement — the address it lives at must be a multiple of its size. A short (2 bytes) must be at an even address; an int (4 bytes) must be at an address divisible by 4, etc.
| Type | Size | Notes |
|---|---|---|
| char | 1 byte | |
| short | 2 bytes (16 bits) | |
| int | 4 bytes (32 bits) | |
| long | 4 or 8 bytes | Platform-dependent; use int32_t/int64_t for guaranteed width |
| float | 4 bytes | Uses floating point representation |
| double | 8 bytes (64 bits) | 4-byte aligned on some Linux ABIs; uses floating point |
| pointer | 4 or 8 bytes | 4 bytes on 32-bit, 8 bytes on 64-bit |
std::int32_t, std::int64_t, etc. from <cstdint>) over long and similar platform-dependent types when exact size matters."32-bit" and "64-bit" refer to the register size, which determines pointer size and how much RAM is addressable (32-bit registers can only reference ~3.5 GB RAM).
| Term | 32-bit | 64-bit |
|---|---|---|
| doubleword | 4 bytes | 8 bytes |
| word | 4 bytes | 8 bytes |
| halfword | 2 bytes | 4 bytes |
| byte | 1 byte | 1 byte |
1 GB = 1000 MB, 1 MB = 1000 KB, 1 KB = 1000 B
When the compiler lays out a struct in memory, it inserts invisible padding bytes between members to ensure each member is properly aligned. This can make a struct larger than the sum of its members.
// As written — appears to be 8 bytes
struct MixedData {
char Data1; // 1 byte
short Data2; // 2 bytes
int Data3; // 4 bytes
char Data4; // 1 byte
};
// After compilation on a 32-bit machine — actually 12 bytes!
struct MixedData {
char Data1; // 1 byte
char Padding1[1]; // 1 byte padding so Data2 is 2-byte aligned
short Data2; // 2 bytes
int Data3; // 4 bytes
char Data4; // 1 byte
char Padding2[3]; // 3 bytes tail padding so struct size is multiple of 4
};
Declaring members in decreasing size order eliminates all internal padding because each member is already naturally aligned by the time it's placed:
struct MixedData {
char Data1;
short Data2;
int Data3;
char Data4;
};
struct MixedData {
int Data3; // largest
short Data2; // medium
char Data1; // small
char Data4; // small
};
#pragma packTo force the compiler to use 1-byte alignment (no padding at all), wrap the struct in #pragma pack directives:
#pragma pack(push, 1)
struct PackedData {
char a;
int b;
short c;
};
#pragma pack(pop)
An empty class or struct has a size of at least 1 byte — never 0.
class Empty {};
sizeof(Empty); // 1 (not 0)
This is required so that every object has a unique address — two distinct Empty objects must not share the same address, which a size of 0 would make impossible.
std::unique_ptr exploits this to store a deleter with no overhead.A real-world example of why alignment and cache behavior matters in game development:
| Property | Value |
|---|---|
| CPUs | 8 × Jaguar cores (x86-64, not ARM) |
| Bus width | 32 bytes |
| Cache line size | 64 bytes (a full cache line is "hot data") |
| L2 hit (same cluster) | ~26 cycles |
| L2 miss (other cluster) | ~190 cycles |
| Main RAM access | 26 cycles + ~100 ms latency |