3 ms·
"was never guaranteed to work by the C standard" It was, on x86, before of compilers emitting opcodes not supporting unaligned memory accesses, because x86 CPU
by faragon 8y ago
"was never guaranteed to work by the C standard"
It was, on x86, before of compilers emitting opcodes not supporting unaligned memory accesses, because x86 CPUs guaranteed safe operation on unaligned memory accesses.
Don't get me wrong, of course it is a good practice writing code not relying on CPU-specific characteristics. The problem is that there is a ton of software for x86 that becomes not reliable when recompiled with -O3 on x86-64 (with hard to catch situations, e.g. passing tests, but with random crashes depending on the data being handled, etc.).
- heinrich5991 8y agoWhat do you mean by "guaranteed"? Was there some specification (e.g. compiler manual or so) that said it? Or did you rely on not-specified behavior? If it's the latter, I wouldn't call that "guaranteed".
- faragon 8y agoIntel CPUs guaranteed correct operation on unaligned accesses. In fact, back in the day, transparent unaligned memory access support, and a strong memory model for SMP, were very strong selling points for Intel vs most RISC vendors. The "problem" on Intel CPUs started when SIMD instructions not supporting unaligned memory were being used for optimizing generic code. Which is a very good thing, of course. The only problem is that there is many bad quality code around that was written with the assumption of x86 CPUs being "safe" in that regard.
- obl 8y agoThat's fine if you're writing assembly. Compilers are free to use UB from the standard to optimize and absolutely do not guarantee you to emit machine loads and store naively as specified in the C source. At least for clang I'm pretty sure they decided _not_ to give knowledge of, e.g., the zero low bits of an int pointer to the optimizer since many people are relying on it. That might not be the case in the future or another compiler. Here is a thread discussing that http://lists.llvm.org/pipermail/llvm-dev/2016-January/094012.html http://lists.llvm.org/pipermail/llvm-dev/2016-January/094012...
- faragon 8y agoSure. And I love compilers generating very fast code. My point was that there is a ton of code written for x86 on assumptions that are no longer true when compiled with -O3 flags. Fortunately, open source code is less affected because usually target the generic case. However, for private code is a huge problem and risk. In my opinion, code intended to operate on x86 processors should be compiled with -O3 only in the case of high quality software, and if the quality can not be assured, it should be compiled with -O2 (at least when compiled with GCC and CLang).
- kbenson 8y agoThe problem is the same as it's always been. C made no guarantees about a specific behavior in some cases, but people learned that a specific compiler and platform combination exhibited specific behavior in those cases, so took advantage of that to write code that used that exhibited behavior. Then the chickens came home to roost as the platforms added new capabilities and the compilers changed, in completely spec compliant ways, mind you, to take advantage of those capabilities. There seems to be a lot of C code written not to spec, but to empirically observed behavior in the wild. People writing "incorrect" programs that function by happenstance isn't new, and the assumptions made when they were written were never true, they just happened to conform to (wrong) expectations for a while.
- pjmlp 8y agoYou still see this a lot nowadays, specially those that only use gcc and clang, without experience writing actual portable C code.
- geofft 8y agoI think you're agreeing with what everyone else is saying now - there never was any "guarantee", there was just "bad quality code around that was written with the assumption." This wasn't guaranteed to work from C either, since compilers were still free to do things like assume that the bottom two bits of a uint32_t * were zero. However, probably -mno-sse or something will solve your problem (where "your problem" is defined as "Intel used to guarantee something in one of its ways of handling data, and in a newer architecture revision, they introduced a faster mechanism for the same calculations that no longer guarantees it.")