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).
GCC always assumes aligned pointer accesses (2020)
111–120 of 128 posts
Re: GCC always assumes aligned pointer accesses (2020)
#112Earlier 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…
Loads of architectures can't do misaligned memory access. Even x86 has problems when variables span cache lines. The compiler usually deals with this for the programmer, e.g. by rounding the address down then doing multiple operations and splicing the result together.
Less common is support for atomic RMW access to unaligned location. x86 does support it but crossing a cache line causes the operation to be very slow.
Re: GCC always assumes aligned pointer accesses (2020)
#113The 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…
All C compilers implement the C abstract machine. It is not used to justify miscompiling code, it is used to specify behavior of compiled code.
> We need a C interpreter
Interpreter or not is not relevant, there must be some misconception. Any behavior you can implement with an interpreter can be implemented with compiled code. E.g., add a test and branch after each integer operation if you want to crash on overflow.
> 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.
As others have mentioned there are static and dynamic checkers (sanitizers) that test for such things nowadays. In compiled, not interpreted code, mind you.
> If only to point out how hilariously absurd the ISO C UB rules are and how nobody actually follows them.
It's not that bad.
> 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."
The spec uses implementation defined behavior for that. Although you can argue that they went the wrong way on some choices -- signed integer overflow "depends on the machine at hand" in the first K&R, which you could say would be reasonable to call it implementation specific and enumerate the behaviors of supported machines.
C had a long history with hardware manufacturers, compiler writers, and software developers though, so the standard can never universally please everybody. The purpose of standardization was never to make something that was easiset for software development, ignoring the other considerations. So a decision is not an example of design by committee gone wrong just because happened to be worse for software writers (e.g., choosing to make overflow undefined instead of implementation dependent). You would have to know why such a decision was made.
Re: GCC always assumes aligned pointer accesses (2020)
#114Earlier 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…
> 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. This is generally not true.
Re: GCC always assumes aligned pointer accesses (2020)
#115Earlier quoted context omitted.
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…
The general problem with this argument is that “do what the hardware does” is actually not easy to reason about. The end results of this typically are impossible to grok.
Re: GCC always assumes aligned pointer accesses (2020)
#116Earlier quoted context omitted.
What you are talking about is implementation-defined behavior. It exists in the C standard separately from the undefined behavior.
Implementation Defined behavior means the standards authors provided a list of possible behaviors, and compiler authors must pick one and document which they picked. Unspecified behavior is more what you're thinking of, though in that case the standard still provides a list of possibilities that compiler authors have to pick from, they just don't have to document it or always make the same choice for every program. T…
The standard definitely does not require implementations to pick from a list of possible behaviors. All the standard requires is that the implementation document the behavior.
For example, the behavior on integer demotion is implementation-defined and there's no list of possible behaviors:
> When an integer is demoted to a signed integer with smaller size, or an unsigned integer is converted to its corresponding signed integer, if the value cannot be represented the result is implementation-defined.
> Unspecified behavior is more what you're thinking of, though in that case the standard still provides a list of possibilities that compiler authors have to pick from
That contradicts the standard's definition of unspecified behavior. For example, from the C89 draft (emphasis added) [0]:
> Unspecified behavior --- behavior, for a correct program construct and correct data, for which the Standard imposes no requirements.
Re: GCC always assumes aligned pointer accesses (2020)
#117Earlier 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.
For C to be portable this needs to be undefined behaviour because there are CPUs that don’t support unaligned access
Re: GCC always assumes aligned pointer accesses (2020)
#118Earlier quoted context omitted.
For C to be portable this needs to be undefined behaviour because there are CPUs that don’t support unaligned access
It doesn't need to be undefined to say it crashes on some architectures.
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
Re: GCC always assumes aligned pointer accesses (2020)
#119The 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…
This line in particular really bugs me: > The present blog post brings bad, and as far as I know, previously undocumented news. Even if you really are targeting an instruction set without any memory access instruction that requires alignment, GCC still applies some sophisticated optimizations that assume aligned pointers. I could have told you this was true ~20 years ago, and the main reason I'm so conservative in ho…
Re: GCC always assumes aligned pointer accesses (2020)
#120Earlier quoted context omitted.
It doesn't need to be undefined to say it crashes on some architectures.
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