Live data from Hacker News

GCC always assumes aligned pointer accesses (2020)

trust-in-soft.com

121–128 of 128 posts

Re: GCC always assumes aligned pointer accesses (2020)

#121

Earlier quoted context omitted.

I guess it could also be implementation defined My point here is that you can’t have “everything works as it does in the native assembly language” and “portable assembly” at the same time because if you rely on implementation defined or undefined behaviour then it’s not portable any more

That depends on what you mean by "portable". I think being able to use the same code across many platforms is enough to qualify. Being able to access raw machine behavior is part of the premise of portable assembly, not a disqualifier.

It’s definitely much more portable than assembly, but code that relies on unaligned pointer accesses won’t work on every platform

Re: GCC always assumes aligned pointer accesses (2020)

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

> 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". This view is alienating systems programmers. You're right that that's what the standard says, but nobody actually wants that except compiler writers trying to juice unrealistic benchmarks. In practice programmers want to alias thing…

My UB links list is getting on in years, but somehow remains vaguely relevant.

"These people simply don't understand what C programmers want": https://groups.google.com/forum/#!msg/boring-crypto/48qa1kWi...

"please don't do this, you're not producing value": http://blog.metaobject.com/2014/04/cc-osmartass.html

"Everyone is fired": http://web.archive.org/web/20160309163927/http://robertoconc...

"No sane compiler writer would ever assume it allowed the compiler to 'do anything' with your code": http://web.archive.org/web/20180525172644/http://article.gma...

Re: GCC always assumes aligned pointer accesses (2020)

#123
post #23

Earlier quoted context omitted.

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, and unaligned memory accesses used to be defined to work correctly on x86. There are a bunch of misconceptions here: - unaligned loads were never implementation defined, they are undefined; - even if they were implementation defined, this would give the compiler the choice of how to define them, not the instruction set; - unaligned memory accesses on x8…

Here's a link to the final C89 draft spec (the ratified spec is paywalled):

https://www.open-std.org/JTC1/sc22/wg14/www/docs/n1256.pdf

From section 6.7.2.1, semantics #10:

> The alignment of the addressable storage unit is unspecified.

This is for struct field access, but it clearly implies the compiler can choose to use unaligned struct fields. Also, the size of the integer types are all implementation defined:

then #12:

> Each non-bit-field member of a structure or union object is aligned in an implementation- defined manner appropriate to its type.

Alignment is defined as:

> requirement that objects of a particular type be located on storage boundaries with addresses that are particular multiples of a byte address

It doesn't say which multiple. 1 is a multiple. (So is 0.5, just in case the complier wants to go nuts with arcane code gen.) The spec even allows chars to be 7 bits. I didn't bother looking up the definition of byte in the spec for those architectures. (7 bits? 8 bits?)

In section 6.2.5, they talk about implementation-defined restrictions on integer types + alignment requirements:

> For each of the signed integer types, there is a corresponding (but different) unsigned integer type (designated with the keyword unsigned) that uses the same amount of storage (including sign information) and has the same alignment requirements.

So, the alignment of integers has to be the same for signed + unsigned types. That still doesn't say byte-aligned integers are disallowed.

Later:

> An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned,

Again, the alignment behavior is clearly implementation-defined.

I can't find a definition of implementation in the spec, but it clearly includes the compiler, standard library, and operating system. There is this quote:

> For implementations with a signed zero (including all IEC60559 implementations)

which, according to the IEC60559 abstract "An implementation of a floating-point system conforming to this standard may be realized entirely in software, entirely in hardware, or in any combination of software and hardware." I doubt they were trying to constrain floating point to be done in software by compilers, so it's pretty clear they intended to incorporate the physical hardware in the definition of the "implementation".

Later, they say:

> ...is defined if and only if the implementation supports the floating-point exception

which was definitely in the realm of hardware support back in 1989. Some later sections says that some macros (such as for FMA) are defined iff the implementation implements the primitive in hardware, and not just software.

Re: GCC always assumes aligned pointer accesses (2020)

#124
post #23

Earlier quoted context omitted.

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.

See sibling comment. The alignment requirements are implementation defined, and any multiple is legal. 1 byte is definitely a legal multiple.

Re: GCC always assumes aligned pointer accesses (2020)

#125

Earlier quoted context omitted.

Unaligned memory accesses are undefined behavior in C. If you're writing C, you should be abiding by C rules. "Used to work correctly" is more guesswork and ignorance than "abiding by C rules". In C, playing fast&loose with definitions hurts, BAD. Frankly, I'd be ashamed to write this blog post since the only thing it accomplishes is exposing its writers as not understanding the very thing they're signaling expertise…

What makes you think they don't understand it? They acknowledge that it is UB. I read them as realistic, since they know that people rely on C compilers working a certain way. They even wrote an interpreter that detects UB: https://github.com/TrustInSoft/tis-interpreter I understand why people like the compiler being able to leverage UB. I suspect this philosophy actually makes Trust-In-Soft more money: You could arg…

I made a comment a few levels up to a sibling where I point out the parts of the C89 spec that are relevant.

Alignment requirements for integers are implementation defined, not undefined behavior. On x86, the implementation used to define the alignment requirement to be one byte.

In fact, if you've do enought hardware register and bus-level (e.g., PCIe) programming, you'll quickly realize that there are all sorts of other exotic implementation-defined alignment constraints on modern systems.

Re: GCC always assumes aligned pointer accesses (2020)

#126
post #125

Earlier quoted context omitted.

What makes you think they don't understand it? They acknowledge that it is UB. I read them as realistic, since they know that people rely on C compilers working a certain way. They even wrote an interpreter that detects UB: https://github.com/TrustInSoft/tis-interpreter I understand why people like the compiler being able to leverage UB. I suspect this philosophy actually makes Trust-In-Soft more money: You could arg…

I made a comment a few levels up to a sibling where I point out the parts of the C89 spec that are relevant. Alignment requirements for integers are implementation defined, not undefined behavior. On x86, the implementation used to define the alignment requirement to be one byte. In fact, if you've do enought hardware register and bus-level (e.g., PCIe) programming, you'll quickly realize that there are all sorts of…

Pretty much everything you wrote in that comment is wrong since you're interpreting the spec in a way that's clearly not what the spec describes (e.g. the spec is talking about alignment requirements for conversions, but you generalize it to "alignment requirements" which is dead wrong).

Re: GCC always assumes aligned pointer accesses (2020)

#127
post #124

Earlier quoted context omitted.

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

See sibling comment. The alignment requirements are implementation defined, and any multiple is legal. 1 byte is definitely a legal multiple.

Unaligned memory access is UB period, no ifs no buts.

Re: GCC always assumes aligned pointer accesses (2020)

#128
post #97

As others have pointed out, GCC is completely allowed to do this because unaligned access is UB. So the problem is not that GCC assumes your code has no UB. The issue is that the C (and C++) specifications persist in this obnoxious and odious desire to label definable behaviour as UB, with no justification. All of the arguments about needing UB to support different hardware fail immediately to the simple fact that th…

Exactly this. At this point the obsession with categorising potentially useful & useable behaviour as UB should be widely acknowledged.
Post reply on HN