Live data from Hacker News

Falsehoods programmers believe about undefined behavior

predr.ag

201–210 of 233 posts

Re: Falsehoods programmers believe about undefined behavior

#201
post #185

Earlier quoted context omitted.

It should also warn if there are infinite loops, so the dev can know whether it will ever halt.

Infinite loops are undefined behavior in C++.

With some exceptions. In C++ infinite loops doing IO, accessing volatile variables or atomics are not undefined.

Hence for(;;) std::this_thread::sleep_for(1s) is not UB.

C is even more lenient.

Re: Falsehoods programmers believe about undefined behavior

#202

UB is not allowed in a constant expression in c++, which is a good reason to put constexpr in front of as many things as you can.

While theoretically true, there are a whole bunch of undefined behaviors that are not caught in constexpr context in practice. In particular unsequenced operations on the same object are typically not caught.

It's still super useful though, and more common language UBs are caught.

Re: Falsehoods programmers believe about undefined behavior

#203
post #32
post #22

13. But if the line with UB isn't executed, then the program will work normally as if the UB wasn't there. 14. Okay, but if the line with UB is unreachable (dead) code, then it's as if the UB wasn't there. 15. If the line with UB is unreachable code, then the program won't crash because of the UB. 16. If the line with UB is unreachable code, then the program will at least stop running somehow and at some point. This…

> This is nonsense. The line with UB has to be reached for the execution to be undefined. Check the footnote at item 14, it links to a page which shows one example of how a line with UB can be reached (basically: the optimizer can reorder the code so that parts of the line with UB will run much earlier than you'd expect).

That example specifically states:

> Right now, we have the fundamental principle that dead code cannot affect program behavior.

Re: Falsehoods programmers believe about undefined behavior

#204
post #22

13. But if the line with UB isn't executed, then the program will work normally as if the UB wasn't there. 14. Okay, but if the line with UB is unreachable (dead) code, then it's as if the UB wasn't there. 15. If the line with UB is unreachable code, then the program won't crash because of the UB. 16. If the line with UB is unreachable code, then the program will at least stop running somehow and at some point. This…

Looks like you believe in some falsehoods most programmers believe about UB. Well, you are not alone.

No, the commenter is right, at least for Rust (can't say for other languages). UB is a property of a particular execution of a program, it happens when code is executed on the abstract machine. As the blog post linked from the article (point 14, footnote 6) states:

> Right now, we have the fundamental principle that dead code cannot affect program behavior.

Re: Falsehoods programmers believe about undefined behavior

#205
post #153

Earlier quoted context omitted.

I think memcpy is fine because it operates on a special type that is allowed to alias anything. Strict aliasing has other fun issues like the impossibility of implementing malloc-like functions or the lack of any requirement for access to non-char members of structs to work at all[0]. [0]: https://stackoverflow.com/questions/49298704/how-reason-abou...

memcpy is UB because it reads padding bytes in structs. memmove fails as it requires pointer comparisons between separate allocations, which is UB.

reading padding bytes is not UB.

Comparing unrelated pointers is unspecified, not undefined. It's also an implementation detail of memmove. It can use a magical total order comparison of pointers that is otherwise unavailable to users of the language.

Re: Falsehoods programmers believe about undefined behavior

#207
post #22

13. But if the line with UB isn't executed, then the program will work normally as if the UB wasn't there. 14. Okay, but if the line with UB is unreachable (dead) code, then it's as if the UB wasn't there. 15. If the line with UB is unreachable code, then the program won't crash because of the UB. 16. If the line with UB is unreachable code, then the program will at least stop running somehow and at some point. This…

Everyone's getting confused about the word "reach". If the execution of a program triggers UB at any point then its behavior is undefined at all points, even before the UB was triggered. But the compiler does have to respect and preserve the behavior of any completely UB-free execution of your program, even if other executions (say with different input) could trigger UB.

So we could say, unreachable UB is fine, but if you do reach it, then it doesn't matter when you reached it.

Re: Falsehoods programmers believe about undefined behavior

#208
post #8

Earlier quoted context omitted.

> gcc screwing the developer over because it was UB when they thought it was just implementation defined No, the developer thought "UB" produced an integer with an undefined (but still valid integral?) value. They misunderstood what UB is, not whether or not something was UB.

That's from the spec POV. On x86 for example, signed int overflow is well defined.

It’s well-defined on x86, but the compiler is allowed to insert INTO instructions (which trigger an interrupt on overflow), which is effectively UB (as the interrupt routine is outside the scope of the C language).

Re: Falsehoods programmers believe about undefined behavior

#209

Earlier quoted context omitted.

Yeah they are and that's too bad. HWASan is another option that reduces the overhead but would only work on a core that had MTE (which your microcontroller is not as likely to have).

Actually it is an enhanced armv7 which might work. Though officially HWASan requires armv8. Besides that we have Zephyr stack and heap overflow detection, but it is not quite as accurate as ASan, and does not handle cases UBSan does.

gwp-asan (like electric fence) is another option for invalid access to heap-allocated buffers. Requires an MMU and creates additional TLB pressure w/some allocation overhead, but no instrumentation overhead and no access overhead.

Re: Falsehoods programmers believe about undefined behavior

#210

UB is not allowed in a constant expression in c++, which is a good reason to put constexpr in front of as many things as you can.

While theoretically true, there are a whole bunch of undefined behaviors that are not caught in constexpr context in practice. In particular unsequenced operations on the same object are typically not caught. It's still super useful though, and more common language UBs are caught.

That's a compiler bug though, right? Doesn't the standard disallow UB in constexpr?
Post reply on HN