8 ms·
With Clang 13 you can literally format your hard drive using undefined behavior
- rurban 6y agoWhy did nobody come up with patches for the insane gcc and clang ub optimizations yet? Make it a cmdline flag, issue a warning or such? Anyone seen such patches? gcc at least issues a default warning on this compiler insanity.
- jart 6y agoBecause unless you turn off the optimizer entirely it's just a whack-a-mole game as these compilers evolve. There's still a lot of people out there using versions as old as 4.7.4, 4.2.1, and even 3.x series GCC. Someday someone's going to build an x-ray machine and then there'll be a dumb ways to die video that galvanizes those people into forking it.
- JdeBP 6y agoThe bug report is better reading: https://bugs.llvm.org/show_bug.cgi?id=49599 https://bugs.llvm.org/show_bug.cgi?id=49599
- jart 6y agoThe issue seems to miss the heart of the problem. We know GCC and Clang have both intended for some time to treat undefined behavior as an opportunity to do whatever they want. If we assume the loop doesn't halt, we can remove the RET instruction. If we assume it does halt then we can remove the loop. Clang's internal model at HEAD appears to be assuming both outcomes happen simultaneously, which is clearly a bug, but could also indicate some kind of deeper policy change surrounding the liberties which are taken with behaviors that are undefined according to the C standard.
- josephcsible 6y ago> Clang's internal model at HEAD appears to be assuming both outcomes happen simultaneously, which is clearly a bug How is it clearly a bug? Undefined means undefined.
- kadoban 6y agoBecause in practice, compilers are expected to do more than the language standard requires of them, and this resulting behavior is very dangerous.
- souprock 6y agoThe trouble dates back to the original standardization of C. An expectation of pre-standard C was left out of the standard: behavior of things like integer overflow could be determined by looking at the CPU documentation. It would have been difficult to turn that into an unambiguous requirement in the standard, and it is unlikely that people imagined what future compilers might do. In the decades since, benchmark competition has given us the hostile mess we have today.
- jart 6y agoUndefined doesn't mean contradiction in the sense that anything becomes possible. It just means it can be defined however you want, and if you choose an unsound definition then that reflects on you. Think about the history of how X3J11 was able to get people like UNIVAC and EDVAC to agree on the C standard even though they had wildly different ideas on how things like how the sign bit should work. The only way to forge a compromise is to simply say, OK, the standard won't broach that topic, keep doing what you're doing.
- josephcsible 6y ago> in the sense that anything becomes possible In C and C++, that's exactly what undefined behavior means. I think you're confusing it with unspecified behavior.
- souprock 6y agoThe behavior is hostile and dangerous, but legal. If undefined behavior would happen during an execution of a program, then that entire execution of the program is undefined behavior from the start. Since all possible executions of this program will lead to undefined behavior, the compiler was free to emit any other program. It is permitted to get rid of all the code. You could say that Clang 13 missed an optimization opportunity here. It could have produced an empty file.
- jart 6y agoObligatory Meme: https://justine.lol/undefined.png https://justine.lol/undefined.png
- PhantomGremlin 6y agoBest comment from the twitter responses: You know shit is serious when someone threatens to format the drive to btrfs
- lupire 6y agoIt's a little complicated to see the key point, but what happens is: * The loop in f1 guaranteed to overflow int i if it's executed, but that's undefined behavior. * Compilers sometimes delete code with undefined behavior, since that's the most efficient possible implementation. * Deleting undefined behavior leaves an empty function. * (Bug?) Empty function gets optimized a way to completely nothing, not even "enter and then exit". Edit: This comment explains the "missing exit" better. https://news.ycombinator.com/item?id=26499110 https://news.ycombinator.com/item?id=26499110 * Bug: the empty function f1 gets an address anyway, but 0 code; which makes execution fall through to whatever's next; in this case, it's f2's implementation. * So, calling f1 jumps to the address where f2 is, and f2 runs, which isn't what you want. "Format your hard drive" just means that "call an arbitrary different function".
- karmakaze 6y agoWith the cloud/github/etc now, 'format your hard drive' is not what it used to be.
- deleted 6y ago[deleted]
- AdamJacobMuller 6y agoThanks for the explanation. When I saw this originally a few hours ago I went to the comments to see what was going on, but, you weren't here yet and I was disappointed :)
- BenFrantzDale 6y agoIs the compiler allowed to refuse to compile UB if it sees it? Clearly it sees it and is optimizing it away; why not just give a compile error?
- souprock 6y agoSuppose the program does UB only when run it with an argument longer than 3 characters, but you never run it that way. It's OK.
- BenFrantzDale 6y agoI understand that it has to be OK for functions to invoke UB if their preconditions aren’t met. And I guess you could have a pointer to this function and thereby want it to exist without ever invoking UB. But to me a function that can’t be called without UB really should be a compile error. I’m trying to think of counterexamples...
- a0-prw 6y agoIf your culture is broken at its heart, you will never be whole.