Live data from Hacker News

GCC always assumes aligned pointer accesses (2020)

trust-in-soft.com

41–50 of 128 posts

Re: GCC always assumes aligned pointer accesses (2020)

#41
post #23
post #2

The arguments in this blogpost are fundamentally flawed. The fact that they opened a bug based on them but got shut down should have raised all red flags. When compiling and running a C program, the only thing that matters is "what the C abstract machine does". Programs that exhibit UB in the abstract machine are allowed to do "anything". Trying to scope that down using arguments of the form "but what the hardware do…

Honestly, I think you are both incorrect. C has always had a concept of implementation defined behavior, and unaligned memory accesses used to be defined to work correctly on x86. Intel added instructions that can’t handle unaligned access, so they broke that contract. I’d argue that it is an instruction set architecture bug. Alternatively, Intel could argue that compilers shouldn’t emit vector instructions unless th…

> C has always had a concept of implementation defined behavior,

Surely only after standardization tho?

Re: GCC always assumes aligned pointer accesses (2020)

#42
They are confused, and seem not to realize that ABIs exist, and often specify alignment requirements. They seem to believe there are just ISA and architecture specs.

When you compile for Linux x86_64 ABI, gcc assumes that the stack is 16 byte aligned because it’s required by the ABI.

Regardless of whether the ISA needs it.

If they want the compiler to make no assumptions about aligned accesses, they would need to define an ABI in GCC that operates that way and compile.with it. They were historically supported (though its been years since I looked)

Re: GCC always assumes aligned pointer accesses (2020)

#43
> The C standards, having to accommodate both target architectures where misaligned accesses worked and target architectures where these violently interrupted the program, applied their universal solution: they classified misaligned access as an undefined behavior.

No. If the C standard wants to accommodate different target architectures, they use implementation-specified behavior. The undefined behavior is just polite way to say that the code is buggy.

The C standard just requires natural alignment even on architectures that allows unaligned accesses.

Re: GCC always assumes aligned pointer accesses (2020)

#44
post #12
post #2

The arguments in this blogpost are fundamentally flawed. The fact that they opened a bug based on them but got shut down should have raised all red flags. When compiling and running a C program, the only thing that matters is "what the C abstract machine does". Programs that exhibit UB in the abstract machine are allowed to do "anything". Trying to scope that down using arguments of the form "but what the hardware do…

That's what the author meant when he said "The shift of the C language from “portable assembly” to “high-level programming language without the safety of high-level programming languages”" Back in the 1980s, C was expected to do what hardware does. There was no "the C abstract machine". The abstract machine idea was introduced much later. > The arguments in this blogpost are fundamentally flawed. The "fundamentally f…

How does C do what hardware does and store things in registers when it can?

Re: GCC always assumes aligned pointer accesses (2020)

#45

If you're going to read byte-level data you should be using a char pointer. The author also speculates on how common this "bug" is. I'd say 15000 Debian packages that work properly indicates that just about nobody is relying on this undefined behavior.

For one, the linux kernel itself relies on this UB - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93031#c5, linked from OP.

And indeed linux would hit UBSAN reports on those, but just disables it if native unaligned load/store is configured - last paragraph of https://github.com/torvalds/linux/blob/706a741595047797872e6...

At present there's almost no reliance on this UB by compilers on something that actually has a chance of affecting real code, so it's not particularly unexpected that software appears to work.

Re: GCC always assumes aligned pointer accesses (2020)

#46
post #2

The arguments in this blogpost are fundamentally flawed. The fact that they opened a bug based on them but got shut down should have raised all red flags. When compiling and running a C program, the only thing that matters is "what the C abstract machine does". Programs that exhibit UB in the abstract machine are allowed to do "anything". Trying to scope that down using arguments of the form "but what the hardware do…

The blog post is also kind of unhinged because in the incredibly rare cases where you would want to write code like this you can literally just use the asm keyword.

I think it's also worth considering WHY compilers (and the C standard) make these kinds of assumptions. For starters, not all hardware platforms allow unaligned accesses at all. Even on x86 where it's supported, you want to avoid doing unaligned reads at all costs because they're up to 2x slower than aligned accesses. God forbid you try to use unaligned atomics, because while technically supported by x86 they're 200x slower than using the LOCK prefix with an aligned read.[^1] The fact that you need to go through escape hatches to get the compiler to generate code to do unaligned loads and stores is a good thing, because it helps prevent people from writing code with mysterious slowdowns.

Writing a function that takes two pointers of the same type already has to pessimize loads and stores on the assumption that the pointers could alias. That is to say, if your function takes int p, int q then doing a store to p requires reloading q, because p and q could point to the same thing. Thankfully in some situations the compiler can figure out that in a certain context p and q have different addresses and therefore can't alias, this helps the compiler generate faster code (by avoiding redundant loads). If p and q are allowed to alias even when they have different addresses, this would all go out the window and you'd basically need to assume that all pointer types could alias under any situation. This would be TERRIBLE for performance.

[^1]: https://rigtorp.se/split-locks/

Re: GCC always assumes aligned pointer accesses (2020)

#47
post #44
post #12

Earlier quoted context omitted.

That's what the author meant when he said "The shift of the C language from “portable assembly” to “high-level programming language without the safety of high-level programming languages”" Back in the 1980s, C was expected to do what hardware does. There was no "the C abstract machine". The abstract machine idea was introduced much later. > The arguments in this blogpost are fundamentally flawed. The "fundamentally f…

How does C do what hardware does and store things in registers when it can?

It doesn't, it is up to the compiler and optimizer to decide how to go at it.

Vector instructions, replacing library functions with compiler intrisics, splitting structs across registers and stack, unrolling loops are all examples absent from the language standard.

Re: GCC always assumes aligned pointer accesses (2020)

#49
post #26

In a project I'm working on[0], there's an array object type used throughout, which can sometimes point to arbitrary data elsewhere. In a funky edge-case[1], such an array can be built with an unaligned data pointer. Thus, if gcc/clang started seriously utilizing aligned pointer accesses everywhere, nearly every single load & store in the entire project would have to be replaced with something significantly more verb…

> in C you kinda just have compiler flags, and maybe __attribute__-s if you can spare some verbosity

Which you can use to wrap the unaligned type as a packed struct, i.e.

   struct __attribute__((__packed__)) unaligned_int { int i; };
which has an alignment of 1.

Re: GCC always assumes aligned pointer accesses (2020)

#50
post #18

An example of a recent compile target that breaks on unaligned pointer accesses was asm.js. There, a 32-bit read turns into a read from a JavaScript Int32Array like this: HEAP32[ptr >> 2] The k-th index in the array contains 4 bytes of data, so the pointer to an address must be divided by 4, which is what the >> 2 does. And >> 2 will "break" unaligned pointers because it discards the low bits. In practice we did run…

> WebAssembly, which allows unaligned accesses

And I think we made the right call (other than the vestigial alignment bits in load/store immediates, which AFAIK, no engine is making use of).

Post reply on HN