Remix.run Logo
kccqzy 6 hours ago

Excellent debugging journey.

If I were the author, I would skip the part about using the compiler explorer and reading the assembly. When I write C code, I need to satisfy the rules of the C language. Unless I’m debugging the compiler or dealing with performance issues, my experience is that reading the generated assembler and understanding it is usually a slow way of debugging. The author eventually did compile with -fsanitize=undefined but I would honestly do that first. It prints a nice error message about the exact issue as the author has shown.

direwolf20 6 hours ago | parent | next [-]

I have to disagree. If you merely want to fix the problem, you can stop as soon as you find something that's awry and whose alteration removes the problem. But don't you want to understand the problem? Don't you want to see how the compiler can reasonably generate code that says a bool variable is true and false at the same time?

kccqzy 6 hours ago | parent [-]

It’s about abstraction layers. Most of the time, understanding the generated assembler code isn’t useful when it comes to understanding the problem. It satisfies my curiosity sure, but the problem is at the C level, an undefined behavior.

Understanding what the C compiler generates is interesting, but without a corresponding intuition about the optimizer passes, such understanding is shallow and unlikely to be generalized to other problems in the future. You probably won’t even remember this the next time you debug another undefined behavior. On the other hand, if you were to know the optimizer passes employed by the compiler and could deduce this code from that, then it is a useful exercise to enhance your intuition about them.

exmadscientist 4 hours ago | parent [-]

I think it depends on your experience. I have a lot of experience from the Old Days™ and from developing for microcontrollers, so I find reading assembly very natural and straightforward. When coding for the really small MCUs I've often had the disassembly generated and shown on another window every time I incrementally build, and can check and make sure it's what I was expecting to see.

I do agree that knowledge of compiler optimizations is really important to working this way, though you'll eventually pick them up anyway. I don't see much value in looking at -O0 or -Og disassembly. You want the strongest stuff the compiler can generate if you're going to do this, which is usually either -O3 or -Oz (both of which are strong in their own ways). -O0 disassembly is... just so much pain for so little gain. Besides, -O3 breaks more stuff anyway!

For someone without this level of experience (and who isn't interested in learning)... yeah, I can see why you'd want to do this another way. But if you've got the experience already, it's plenty fast enough.

niobe 4 hours ago | parent | prev [-]

I think that's the kind of intuitive decision that comes from years of troubleshooting experience. It's not obvious that would be the place to start. It's impressive to me at least he got there.