Live data from Hacker News

GCC always assumes aligned pointer accesses

trust-in-soft.com

91–93 of 93 posts

Re: GCC always assumes aligned pointer accesses

#91
post #78

Earlier quoted context omitted.

Do you know if there is a compiler switch that can insert run-time checks any time it makes assumptions which could be invalid (such as “this random pointer is aligned”) and abort with an error message (or something) when it is not true? I think this would be invaluable for tracking down odd bugs caused by things like this.

I have seen it said in another thread that UBSan detects this. If you aren't already using all the sanitizers that come with your {CLang, GCC} compiler, you should! They are great! UBSan detects everything that can be detected without metadata. It would be its job to find this, since this is a simple mask to apply and test at each pointer access. UBSan cannot detect if memory is initialized or if a pointer is valid,…

UBSan does detect and report misaligned pointer accesses in the latest versions of GCC and Clang:

https://gcc.godbolt.org/z/xpSbXL

Re: GCC always assumes aligned pointer accesses

#92
post #73

Earlier quoted context omitted.

This is actually more subtle than one would think. Say you were trying to talk to three UART registers at 0xA000, 0xA004, and 0xA008. It's legal to access: *(volatile uint32_t *)(0xA000); *(volatile uint32_t *)(0xA004); *(volatile uint32_t *)(0xA008); The struct equivalent of this would be something like: struct UART_Peripheral { volatile uint32_t control; volatile uint32_t txdata; volatile uint32_t rxdata; }; struct…

The C standard doesn't define what happens when you cast an integer to a pointer like that. For example I work with a compliant C implementation where this would not work, because it uses fat pointers.

Interesting! I didn't know that. Does uintptr_t exist on your platform? If so, how does it work?

Re: GCC always assumes aligned pointer accesses

#93

This isn't just an issue with GCC but embedded compilers as well. On embedded systems its common to work with packed data structures to maximize serial protocol efficiency. Lets say you have a packed structure with a type of struct MyPackedStruct { uint8_t byteValue; uint32_t intValues[5]; } Normally a compiler would add 3 extra bytes between the uint8_t value and the uint32_t array to keep alignment of the int array…

Forcing packing of a struct isn't possible in standard C, only through compiler extensions. Presumably that's the reason: you have the strange situation where it's legal (and well-defined) to read the member, or to write it, but to take its address and perform a read through that pointer, causes undefined behaviour.

I believe that situation is impossible in standard C.

Post reply on HN