I stumbled on an “hacky” answer recently (this one) where it was mentioned that because (I assume 32bit) C/C++ pointers are usually 4byte aligned the last 2 bits of each pointer are always zero. I don’t understand why this should be the case. Why not use all 32bits to represent an address?
Please disregard the merits of the actual answer I linked to above. I’m only interested in the observation regarding the 2 LSBs.
You may notice the key word “usually” in that statement. “Usually” does not imply “always“. And if something isn’t always true, you can’t assume it to be true and just chop off the last two bits.
Most pointers to live objects will have alignments of at least 4 bytes. However, you can create an array of
chars, and those elements will be byte addressable. That something happens 99% of the time doesn’t mean you can ignore the final 1% where it doesn’t happen.The reason why most pointers are aligned to at least 4 bytes is that most pointers are pointers to objects or basic types that themselves are aligned to at least 4 bytes. Things that have 4 byte alignment include (for most systems):
int,float,bool(yes, really), any pointer type, and any basic type their size or larger.Any object that contains one of these must be aligned to at least the alignment of that object. So an object that stores an
intis aligned to 4 bytes. An object that contains a pointer is aligned to at least 4 bytes. And so forth. Rare is the object that doesn’t include one of these basic types.That’s why. The vast majority of data types you want to point to will have a minimum of 4 bytes of alignment.