最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++23 - What is pointer alignment in C++ and why is it significant in the context of creating undefined behaviour? - Stack Overf

programmeradmin0浏览0评论

I received comments on a recent question which suggests that pointers which are not aligned can created undefined behaviour when dereferenced (at least in newer C++ standards).

My question consists of two parts.

  • I am not sure I fully understand what constitutes an aligned pointer, or more accurately, what might make a pointer address mal-aligned or mis-aligned.

  • Going further, I am certainly not sure why this may cause undefined behaviour.

BTW - since my base level understanding of this subject matter is clearly quite limited, it may be the case that I misunderstood the comments which were made, or did not understand them completely. So it is possible this question doesn't make much sense.

I received comments on a recent question which suggests that pointers which are not aligned can created undefined behaviour when dereferenced (at least in newer C++ standards).

My question consists of two parts.

  • I am not sure I fully understand what constitutes an aligned pointer, or more accurately, what might make a pointer address mal-aligned or mis-aligned.

  • Going further, I am certainly not sure why this may cause undefined behaviour.

BTW - since my base level understanding of this subject matter is clearly quite limited, it may be the case that I misunderstood the comments which were made, or did not understand them completely. So it is possible this question doesn't make much sense.

Share Improve this question edited Feb 6 at 20:06 Remy Lebeau 596k36 gold badges498 silver badges843 bronze badges asked Feb 6 at 19:44 user2138149user2138149 16.8k30 gold badges145 silver badges287 bronze badges 8
  • "Pointer alignment"? May be "address alignment"? – 3CxEZiVlQ Commented Feb 6 at 19:48
  • 2 char buffer[100]; int* p = (int*)&buffer[1]; *p = 1234; Notice that the pointer is intentionally misaligned (on some platforms). On a DEC Alpha, reading or writing to the memory would crash the program (that's due to undefined behavior), or if a compiler flag was provided the OS would "fix up" the misalignment using a trap and low level read/shift/write instructions to place the value into the misaligned memory — albeit x1000 slower than if it were aligned. – Eljay Commented Feb 6 at 19:58
  • Undefined behavior is when the standard doesn't say what happens. :-) All variables will be given the proper alignment by the compiler. So what happens when it is not aligned?! Who knows? How would that even happen? – BoP Commented Feb 6 at 22:15
  • @BoP See this is what gets me as well. If the compiler makes some modifications to ensure alignment of variables, doesn't this suggest that one variable may intersect with another? I am thinking from the point of view of mallocing an array of uint8_t, which is interpreted as a uint64_t followed by a uint8_t followed by a uint64_t. Close packed with no padding. The final element will not be aligned. If the compiler aligns it, and malloc was called to allocate 17 bytes of memory, then presumably the final uint64_t is partially off the end of the allocated block of memory. – user2138149 Commented Feb 6 at 22:23
  • Memory from malloc is properly aligned for all types. If you want to store mixed types in there, use a struct and its members will also be aligned. If you try to store a 64-bit value in the 10th byte, you have done something wrong to get there. – BoP Commented Feb 6 at 22:31
 |  Show 3 more comments

1 Answer 1

Reset to default 4

What is alignment?

Typical memory doesn't deliver data a byte at a time, and typical CPUs don't want it that way. The data bus between them is 2, 4, or even 8 bytes wide. (Sometimes even more, but we'll go with this for now.) Moreover, you can't just read 8 bytes from any address, but only from an address that is divisible by 8. Such an address is called aligned.

So if you want to read 8 bytes from an address that isn't divisible by 8 (unaligned), what can you do? Well, you can read some bytes from the next lower aligned address, and some from the next upper, and then combine those you want together and throw the rest away. That's an unaligned load.

But while you the programmer can do that explicitly, whether the CPU will do it if you give it an unaligned address to load is a different question. Some CPU architectures will (e.g. x86), but usually at the cost of performance. Some won't, and instead will fault. Sometimes it depends on the instruction, e.g. SSE has both an aligned load instruction that will fault on unaligned addresses and an unaligned load instruction that won't.

In programming language terms, where we abstract away from the hardware, types have alignments, e.g. a 4-byte int typically has 4-byte alignment, and so if your int object doesn't sit at an aligned address, it's unaligned, and reading it is undefined behavior.

So why undefined behavior?

Because that's generally how C dealt with differences between platforms. If doing something yields different results on different platforms, then very often the language just says it is undefined. Compare signed integer overflow (has different behavior on some old platforms) or shifting beyond the integer width (has different behavior on some rather recent platforms).

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论