Live data from Hacker News

GCC always assumes aligned pointer accesses (2020)

trust-in-soft.com

71–80 of 128 posts

Re: GCC always assumes aligned pointer accesses (2020)

#71

Earlier quoted context omitted.

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…

While the sentiment is correct as to why compilers makes alignment assumptions, a lot of the details here I think are not quite right. > For starters, not all hardware platforms allow unaligned accesses at all If you're dealing with very simple CPUs like the ARM M0, sure. But even the M3/M4 allows unaligned access. > Even on x86 where it's supported, you want to avoid doing unaligned reads at all costs because they'r…

Yeah even Microsoft's compiler aligns values on appropriate boundaries for performance reasons. DWORDs on DWORD boundaries etc. And if you want to pack the data structure to avoid the gaps in structures there are methods to do so via #pragma options. I think their complaining about what was done for performance reasons shows a great lack of overall understanding. More time researching and less time griping would have served them better.

Re: GCC always assumes aligned pointer accesses (2020)

#72
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…

Great, except no implementation of the C abstract machine actually exists. So you can't test against it. All you have are compilers that use it to justify miscompiling your code.

We need a C interpreter that intentionally implements C machine features that don't correspond to any architectural feature - i.e. pointers are (allocation provenance, offset) pairs, integer overflow panics, every pointer construction is checked, etc. If only to point out how hilariously absurd the ISO C UB rules are and how nobody actually follows them.

My personal opinion is that "undefined behavior" was a spec writing mistake that has been rules-lawyered into absurdity. For example, signed integer overflow being UB was intended to allow compiling C to non-twos-compliment machines. This was interpreted to allow inventing new misbehaviors for integer overflow instead of "do whatever the target architecture does."

Re: GCC always assumes aligned pointer accesses (2020)

#73
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…

Great, except no implementation of the C abstract machine actually exists. So you can't test against it. All you have are compilers that use it to justify miscompiling your code. We need a C interpreter that intentionally implements C machine features that don't correspond to any architectural feature - i.e. pointers are (allocation provenance, offset) pairs, integer overflow panics, every pointer construction is che…

> For example, signed integer overflow being UB was intended to allow compiling C to non-twos-compliment machines.

This is indeed a design mistake, but in another sense. Ordinary arithmetic ops like + or - should throw an exception on overflow (with both signed and unsigned operands) because most of the times you need an ordinary math, not math modulo 2^32. For those rare cases where wrap around is desired, there should be a function like add_and_wrap() or a special operator.

Re: GCC always assumes aligned pointer accesses (2020)

#75

Compilers should just add a --k&r mode to appease these people, but it should also reject ansi code with parse errors.

If a --k&r mode were to be reliable, wouldn't it need to get specified first? Otherwise people would start relying on some edge case. If speed is not a requirement for the --k&r mode, you could just take the tis-interpreter and note that if it runs without UB, it is still much faster than an actual computer was when k&r were active. Would it even be possible to specify a variant of C that contains no UB (e.g. would d…

It could probably only be used with a neural link. It would read your mind, then emit code that matches your perception of what you imagine old compilers did.

Re: GCC always assumes aligned pointer accesses (2020)

#76

The D programming language does not allow the creation of misaligned pointers in code marked as @safe, and in @safe code assumes they are aligned. In @system code you can do whatever you like, but things need to be aligned that are provided to @safe code.

Doesn't look like that changes anything about actual dereferencing though, which is the primary thing discussed - https://godbolt.org/z/4vW5Ksnab still emits an "align 4", which llvm could still assume as UB if violated (though I don't know if it ever does).

Re: GCC always assumes aligned pointer accesses (2020)

#77
post #62
post #22

Earlier quoted context omitted.

If the compiler is so smart, I guess it could insert a memcpy when needed? The standard, you may say.. I would argue it's the standard need to be changed. The modern reading of the standard is not useful as a low-level language and is unsafe as a high-level language.

> If the compiler is so smart, I guess it could insert a memcpy when needed? If I'm reading your comment and the blog post correctly, the compiler would need a memory like access on every multibyte pointer argument where the compiler cannot otherwise prove alignment. Is that correct?

> memory like

I meant memcpy()-like

Re: GCC always assumes aligned pointer accesses (2020)

#78

Earlier quoted context omitted.

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…

While the sentiment is correct as to why compilers makes alignment assumptions, a lot of the details here I think are not quite right. > For starters, not all hardware platforms allow unaligned accesses at all If you're dealing with very simple CPUs like the ARM M0, sure. But even the M3/M4 allows unaligned access. > Even on x86 where it's supported, you want to avoid doing unaligned reads at all costs because they'r…

Your message is more misleading than the GP.

Many architectures sold today still claim unaligned accesses are optional (e.g. all ARM pre-v7, which includes the popular Raspberry Pi Zero). Not to mention that even if they are supported, not all instructions support it (which is the case today on all ARM cores and even on x86).

From the architectures and instructions which may support it, it may have a performance penalty which may range from "somewhat slower" (e.g. Intel still recommends stack alignment, because otherwise many internal store optimizations start giving up) to "ridiculously slower" (e.g. I once had to write a trap handler that software-emulated unaligned accesses on ARM -- on all 32-bit ARMs Linux still does this for all instructions except plain undecorated LDR/STR when the special unaligned ABI is enabled).

And finally, even if the architecture supports it with decent enough performance, it may do it with relaxed atomicity. E.g. even as of today aarch64 makes zero guarantees regarding atomicity of even atomic instructions on unaligned addresses (yes, really). To put it simply because it is a _pain in the ass_ to implement correctly (say programmer does atomic load/store on overlapping addresses with different alignments). This is whether they cross cache lines or not.

i.e. it's as a bad as the GP is saying. You can't just put one example of one processor handling each case correctly to dismiss this claim, because the point is that most processor's don't bother and those who do bother still have severe crippling limitations that make it unfeasible to use in a GP compiler.

And there is still a lot of benefit to packing things up... but it does require way too much care and programmer effort.

Re: GCC always assumes aligned pointer accesses (2020)

#79
post #62
post #22

Earlier quoted context omitted.

If the compiler is so smart, I guess it could insert a memcpy when needed? The standard, you may say.. I would argue it's the standard need to be changed. The modern reading of the standard is not useful as a low-level language and is unsafe as a high-level language.

> If the compiler is so smart, I guess it could insert a memcpy when needed? If I'm reading your comment and the blog post correctly, the compiler would need a memory like access on every multibyte pointer argument where the compiler cannot otherwise prove alignment. Is that correct?

Internally, the compiler could represent it however it wants. LLVM IR's load/store instructions just have an "align" property, which is usually sizeof(the type), but can be set to 1 to mimic memcpy (and indeed llvm/clang immediately translate a memcpy to such - https://godbolt.org/z/7T46a6aqT).

Though it seems that, independent of this, it assumes that an int* in general will be 4-byte-aligned, so e.g. https://godbolt.org/z/aWTEd4s3K still has an "align 4" despite using memcpy. So one must also cast to a char* before using memcpy() to actually have it work. yay for more footguns!

Re: GCC always assumes aligned pointer accesses (2020)

#80
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…

This turns out to be contentious. There are two histories of the C language and which one you get told is true depends on who you ask. 1/ a way to emit specific assembly with a compiler dealing with register allocation and instruction selection 2/ an abstract machine specification that permits optimisations and also happens to lower well defined code to some architectures My working theory is that the language standa…

> My working theory is that the language standardisation effort invented the latter. So when people say C was always like this, they mean since ansi c89, and there was no language before that. And when people say C used to be typed/convenient assembly language, they're referring to the language that was called C that existed in reality prior to that standards document.

But the committee has always had a lot of C compiler developers in it. The people who wrote the C89 standard were the same people who developed many of the C compilers in use before C89. The people who created the reality prior to C89 created the reality after C89. Any perception of "portable assembly" probably stemmed simply from the fact that optimizers were much less sophisticated.

Post reply on HN