Live data from Hacker News

GCC always assumes aligned pointer accesses (2020)

trust-in-soft.com

31–40 of 128 posts

Re: GCC always assumes aligned pointer accesses (2020)

#32

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.

Getting to that point has required years of maintenance work since compiler writers started interpreting more and more undefined behaviour as optimization opportunities. At least now we have UBSAN to actually test for undefined behaviour at runtime.

Re: GCC always assumes aligned pointer accesses (2020)

#33
post #28
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…

To the best of my recollection the “abstract machine” is a C++ism that unfortunately crept into C.

The "abstract machine" is present in the first C standard, published in 1989.

Re: GCC always assumes aligned pointer accesses (2020)

#34
In other words, the result they got is different from the expected one. The keyword here is "expected": if your code contains a part that generates undefined behavior accordingto the standard, then you should have no expectations. What's worth mentioning in this blog post?

Re: GCC always assumes aligned pointer accesses (2020)

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

Undefined and implementation defined are different in C. The number of bits in an int is implementation defined. Unaligned access is undefined.

Re: GCC always assumes aligned pointer accesses (2020)

#36
post #28
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…

To the best of my recollection the “abstract machine” is a C++ism that unfortunately crept into C.

From C89 document:

> 2.1.2.3 Program execution

> The semantic descriptions in this Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant

[...]

> Alternatively, an implementation might perform various optimizations within each translation unit, such that the actual semantics would agree with the abstract semantics only when making function calls across translation unit boundaries. In such an implementation, at the time of each function entry and function return where the calling function and the called function are in different translation units, the values of all externally linked objects and of all objects accessible via pointers therein would agree with the abstract semantics. Furthermore, at the time of each such function entry the values of the parameters of the called function and of all objects accessible via pointers therein would agree with the abstract semantics.

Re: GCC always assumes aligned pointer accesses (2020)

#37

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.

Undefined behavior doesn't necessarily mean the program will exhibit an issue. It could silently break with a future version of the compiler, which it sounds like was the case here

Re: GCC always assumes aligned pointer accesses (2020)

#38
post #19

Earlier quoted context omitted.

It dates to the first standardization of C in 1989. The "C as portable assembly" view ended when ANSI C got standardized, and K&R's 2nd edition was published.

I would argue it's the modern understanding of C standard is flawed. Back in 89, many of those unspecified behavior were understood as implementation/hardware dependent, not undefined. Aliasing was the norm, `restrict` was actually a keyword. Modern C is neither safe nor low-level.

Ascertaining the state of the mind of the C committee in 1989 is difficult, since only the documents from ~late 1996 are consistently available online (the earlier documents are probably sitting somewhere in a warehouse in Geneva, but they may as well not exist anymore).

But definitely by the time C99 came out, it is clear that optimize-assuming-UB-doesn't-happen was an endorsed viewpoint of the committee [1]. C99 also added restrict to the language (not C89 as you suggest), and restrict was the first standardized feature that was a pure UB-optimization hint [2].

It is important to remember that there isn't just one catch-all category of implementation-varying behavior. There is a difference between unspecified behavior, implementation-defined behavior, and undefined behavior. Undefined behavior has been understood, from its inception, as behavior that doesn't constrain the compiler, and often describes behavior that can't be meaningfully constrained (especially with regards to potentially-trapping operations).

[1] The C99 rationale gives an example of an optimization that compilers can perform that relies on assuming UB can't happen--reassociation of integer addition, on one's complement machines.

[2] The register keyword is I believe even in K&R C and would also be qualified as a compiler hint feature, but I note that it prohibits taking the address of the variable entirely, so it doesn't rely on UB. Whereas restrict has to rely on "if these two variables alias, it's UB" to allow the compiler to optimize assuming nonaliasing.

Re: GCC always assumes aligned pointer accesses (2020)

#39
post #19

Earlier quoted context omitted.

It dates to the first standardization of C in 1989. The "C as portable assembly" view ended when ANSI C got standardized, and K&R's 2nd edition was published.

I would argue it's the modern understanding of C standard is flawed. Back in 89, many of those unspecified behavior were understood as implementation/hardware dependent, not undefined. Aliasing was the norm, `restrict` was actually a keyword. Modern C is neither safe nor low-level.

> Back in 89 […] `restrict` was actually a keyword.

Was it? I thought it’s more recent. https://en.wikipedia.org/wiki/Restrict seems to agree (“In the C programming language, restrict is a keyword, introduced by the C99 standard,[1] that can be used in pointer declarations”), as does https://en.cppreference.com/w/c/language/restrict (“restrict type qualifier (since C99)”)

Was there an older usage?

Re: GCC always assumes aligned pointer accesses (2020)

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

> Back in the 1980s, C was expected to do what hardware does. There was no "the C abstract machine".

There was also a huge variety of compilers that were buggy and incomplete each in their own ways, often with mutually-incompatible extensions, not to mention prone to generating pretty awful code.

Post reply on HN