Reputation: 27435
An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated.
That concept is a bit unclear. For instance:
struct B { long double d; };
struct D : virtual B { char c; }
When D is the type of a complete object, it will have a subobject of type B, so it must be aligned appropriately for a
long double
.
What does it mean? sizeof(long double)
is the number of bytes between what in that case??
Upvotes: 4
Views: 267
Reputation: 57784
I completely understand your uncertainty. That might be among the worst attempts I have seen to explain what alignment is.
Think of it in practical terms.
00100000 64 65 66 61 75 6c 74 0a 31 0a 31 0a 31 0a 31 0a |default.1.1.1.1.|
00100010 32 0a 31 0a 33 0a 30 0a 31 0a 34 0a 32 33 0a 31 |2.1.3.0.1.4.23.1|
00100020 39 0a 31 37 0a 35 0a 32 36 0a 32 34 0a 33 0a 38 |9.17.5.26.24.3.8|
00100030 0a 31 32 0a 31 31 0a 31 30 0a 31 34 0a 31 33 0a |.12.11.10.14.13.|
00100040 38 32 0a 38 33 0a 38 34 0a |82.83.84.|
This is a hexdump of arbitrary data. Assume this data has been loaded into memory at the addresses as shown. Since the addresses are written in hexadecimal, it is easy to see the bit alignment.
The data at 0x100000 and 0x100001 could be accessed as a 16-bit aligned value (with a suitable CPU instruction or a 16-bit data access through a C pointer reference). However the data 0x100003 and 0x100004 is not aligned—it spans the 16-bit word at 2 and 3, and the 16-bit word at 4 and 5. The former is 16-bit aligned and the latter is not.
Likewise, the 64-bit (8 byte) value at 0x100030..100037 is 64-bit aligned. But everything until 0x100038 is not.
The alignment characteristics are due to the memory bus hardware which organizes memory accesses into bus cycles. A 16-bit data bus has the ability to fetch 8 bits or 16 bits in one operation, but the latter only if the address is even (least significant address bit is zero). CPUs which allow "odd alignment" perform two successive bus cycles (one even the other odd) to accomplish the operation. Other CPUs simply issue faults for non-aligned bus cycles.
Upvotes: 1
Reputation: 248209
Most CPU's have "preferences" about where data can be stored. When reading or writing to a memory address, the operation may be slower (or completely illegal) if the address doesn't match the data size you try to write. For example, it is common to require that 4-byte integers be allocated starting on an address that is divisible by 4.
That is, an int
stored on address 7
is either less efficient, or completely illegal, depending on your CPU. But if it is stored at address 8
, the CPU is happy.
That is what alignment expresses: for any object of type T
what must its address be divisible by, in order to satisfy the CPU's requirements?"
In C++, the alignment for an object is left implementation-defined (because, as said above, it depends on the CPU architecture). C++ merely says that every object has an alignment, and describes how to determine the alignment of compound objects.
Being "aligned for a long double
" simply means that the object must be allocated so that its first byte is placed in an address that is valid for a long double
. If the CPU architecture specifies the alignment of a long double
to be 10 (for example), then it means that every object with this alignment must be allocated on an address that is divisible by 10.
Upvotes: 7