Email or username:

Password:

Forgot your password?
Marc

When the internet finds some premium nasal demons

25 comments
aeva

@mdiluz Amazing. Really, this is perfectly logical if you think about it. It's safe to remove the while loop because it does not have any side effects, and it is also safe to remove the instructions following the while loop because the loop as written provably doesn't terminate.

Bee O'Problem

@aeva @mdiluz but where does the call to unreachable come from? Your logic only explains the loop being optimized out unless I'm missing something.

RAOF

@beeoproblem @aeva @mdiluz The reasoning I've seen is:
You generate code for main() and unreachable(). You use the UB to dead-code eliminate main(). Now the code for unreachable() is where the code for main() was; ie: it has become the entrypoint.

aeva

@RAOF @beeoproblem @mdiluz if you're missing a main function other functions don't get promoted to main. I tested it out in godbolt earlier, what happens is the ret instruction in main gets optimized out, thus the program counter just advances to the next instruction in memory which is the other function. The entry points for main and the other function still exist.

aeva

@RAOF @beeoproblem @mdiluz gcc and msvc both do what you'd expect. Clang and zig's c++ compiler both optimize away the loop and the return.

Marqin

@beeoproblem @aeva @mdiluz the return call from main() got optimised away and so the CPU doesn’t jump away, and keeps taking further instructions from the assembly, which are the body of unreachable()

DELETED

@aeva @mdiluz but why doesn't also remove the unused function? It's never called so even if the loop terminates, it should never fall through to the function right?

This breaks abstraction/encapsulation, as well as the security and control boundaries functions serve.

Zoe

@AgreeableLandscape @aeva @mdiluz because of linking, the compiler doesn't know if the object will be linked. The function can be called from another object.

aeva

@ekg @AgreeableLandscape @mdiluz this exactly. To Agreeable Landscape's concerns, if you mark "unreachable" as static (indicating it only exists for the translation unit), then clang removes it. It's not a big spooky zero day, this is just how linking works 🤷‍♀️

Jon A. Cruz

@brion @mdiluz oh, clang, you silly little thing. Ya start with extraneous warnings and now we see what's next

Þór Sigurðsson

@mdiluz apparently it doesn't work just everywhere

Louis Dureuil

@thor
Yep, Undefined Behaviour is unreliable. The compiler was written to produce a binary whose behaviour is as described under certain rules, and this program does not respect these rules. It is like using an item in anti-gravity. If it hasn't been specifically designed for this use case, chances are that it assumed gravity. If you're lucky it might work even in anti gravity but you wouldn't count on it. Now the question is if the rules of C++ make sense 🫣
@mdiluz

Marc

@thor yeah, it's mostly because of a specific rule in clang's optimiser

Bee O'Problem

@mdiluz cereal guy... now THAT'S a blast from the past!

ROTOPE~1 :yell:

@mdiluz damn, and I remember when it would take a Cray a good half a minute to complete an infinite loop.

Carl Tessier

@mdiluz Another UB footgun I had completely forgotten about.

Aliciaverse

@mdiluz There's a reason I don't like C++ anymore. Too much undefined behavior. And it doesn't just do a logic bug, it can do anything...

Go Up