Earlier quoted context omitted.
This is a description of an imaginary compiler, evoked by the ANSI/ISO standards documents, which has never existed and will never exist. To understand what the program will do, you just have to understand the compiler behavior on your target platforms. A helpful intuition pump is: imagine the ANSI/ISO specifications simply do not exist; now what? Well, you just continue your engineering practice, the way you would f…
GCC -O1 and clang -O1 will both optimize this function under the assumption that inputs that cause signed integer overflow are never passed: int will_overflow(int a, int b) { int sum = a + b; if (b > 0 && sum
Everything in C is undefined behavior
321–330 of 748 posts
Re: Everything in C is undefined behavior
#322Earlier quoted context omitted.
Many, many programmers come to C (and C++) with a lower-level understanding that actually gets in the way here. They understand that all types "are" just bytes and that all pointers "are" just register-sized integer addresses, because that's how the hardware works and has worked for decades. It's perfectly reasonable to expect any load through `int*` to just load 4 bytes from memory, done and done. They get surprised…
> They understand that all types "are" just bytes and that all pointers "are" just register-sized integer addresses, because that's how the hardware works and has worked for decades. I'd clarify this with "They understand that all values are just bytes" . > Meanwhile, the actual computers we have been using for decades have no problems actually just loading 4 bytes through any arbitrary pointer with zero overhead. It…
Re: Everything in C is undefined behavior
#323Earlier quoted context omitted.
But that seems obvious. You can't load an integer from an unaligned address. It's not only C-level is it. There's no (guarantee across architectures for) machine code for that either.
> You can't load an integer from an unaligned address. You can, and the results are machine specific, clearly defined and well-documented. Ancient ARM raises an exception, modern ARM and x86 can do it with a performance penalty. It's only the C or C++ layer that is allowed to translate the code into arbitrary garbage, not the CPU.
Re: Everything in C is undefined behavior
#324Earlier quoted context omitted.
"volatile" tells the compiler it is _not_ safe to optimise away any read or write, so it can't just optimise that section away at all. > An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2…
Yes, but undefined behaviour is undefined behaviour, and that behaviour can legally be that the code is not emitted at all, volatile (or any other side effect) or not. (and compilers do reason about undefined behaviour when optimising, so this isn't necessarily a completely theoretical argument, though I don't know whether the in compiler's actual logic which of 'don't optimise volatile' or the 'do assume undefined b…
GCC calls that out [0] - volatile means things in memory may not be what they appear to be, and that there are asynchronous things happening, so something that may not appear to be possible, may become so, because volatile is a side-effect.
So about the only optimisation allowed to happen, is combining multiple references.
Clang is similar:
> The compiler does not optimize out any accesses to variables declared volatile. The number of volatile reads and writes will be exactly as they appear in the C/C++ code, no more and no less and in the same order.
[0] https://www.gnu.org/software/c-intro-and-ref/manual/html_nod...
Re: Everything in C is undefined behavior
#325the only people complaining about being able to do awful things are people that do awful things
Re: Everything in C is undefined behavior
#326Earlier quoted context omitted.
The pointer might be something you forced. The compiler needs to do the right thing but if you set the pointer to an unaligned address because you have information on the hardware you can get this undefined situation with nothing the compiler can do about it.
Any reason the hardware pointer can't be accessed via the packed structure? https://news.ycombinator.com/item?id=48205371
Re: Everything in C is undefined behavior
#327Earlier quoted context omitted.
Unless your code targets some exotic architecture, like idk x86.
Not really. Wait until the compiler starts vectorizing your code and using instructions requiring alignment (like the ones with A or NT in the mnemonic).
Re: Everything in C is undefined behavior
#328Earlier quoted context omitted.
Your first paragraph makes it sound as if the compiler will actually generate two reads of the value of some register, which might lead to unexpected effects at runtime for certain special registers. However, this is not at all what UB means in C (or C++). The compiler is free to optimize away the entire block of code where this printf() sequence occurs, by the logic that it would be UB if the program were to ever re…
"volatile" tells the compiler it is _not_ safe to optimise away any read or write, so it can't just optimise that section away at all. > An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2…
Re: Everything in C is undefined behavior
#329feels like https://xkcd.com/1499/ the only people complaining about being able to do awful things are people that do awful things
- unless you are trying to sink it in mercury. then it floats
- unless it is an uranium bar
- go sink uranium bars in mercury yourself
Re: Everything in C is undefined behavior
#330Earlier quoted context omitted.
Not having unaligned access in the language allows the compiler to assume that, for basic types where the aligment is at least the size, if two addresses are different then they don't alias and writes to one can't change the result of reads from the other. That's a very useful assumption to be able to make for optimization - much more useful than yolocasting pointers in a way that could get you unaligned ones.
> if two addresses are different ... Eh, if the compiler knows that two addresses are different at compile time, it also knows how big the difference is.