Live data from Hacker News

Falsehoods programmers believe about undefined behavior

predr.ag

221–230 of 233 posts

Re: Falsehoods programmers believe about undefined behavior

#221

Earlier quoted context omitted.

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 i…

Point 14 explicitly says UB in dead code. The implicit assumption is no UB in live code, otherwise the UB in dead code is a red herring. So the UB is never reached, by the definition of dead code. Unreachable UB is fine. If this wasn't the intended message of point 14, then it's phrased wrong.

Yeah the format of the article makes this mistake extra confusing. The statement in point 14 is in fact true, but the whole premise is that all these statements are supposed to be false.

Re: Falsehoods programmers believe about undefined behavior

#222

Earlier quoted context omitted.

Post author here. I'm very curious about the screen reader idea. If you or someone else is able to confirm what a good screen reader might do currently / what it might do with an empty list element, I'll happily update the post to whatever is the better behavior. I wish there were a best practices doc + a matching linter for accessibility things like this.

I just tested " " in VoiceOver on Mac and nothing gets read. Different screen readers are notoriously inconsistent though. > I wish there were a best practices doc + a matching linter for accessibility things like this. This sounds like it was meant to be a fun tweak/joke for screen readers but it's accessible without. So it's not practical to automate a lot of accessibility checks like this one because it depends on…

> Different screen readers are notoriously inconsistent though.

In other words, UB!

Re: Falsehoods programmers believe about undefined behavior

#223

Earlier quoted context omitted.

> For example, `if (fermats_last_theorem_is_wrong()) {*p == 1} ` will imply to a modern compiler that p is not NULL in the scope where it is defined, even if we now know that this code will never be reached (assuming that function is correctly written). No it won't. Otherwise all precondition checks would be meaningless. The compiler can only assume that it isn't null when fermats_last_theorem_is_wrong() is true. If…

Yes, the part about Fermat's last theorem I wrote is actually obviously wrong, I don't know what exactly I was thinking when I wrote it. The example with the loop though is more to point out that our native understanding of "unreachable" may be different than the compiler's. The same problem could occur without invoking UB if we un-conditionally generate a SIGKILL to our own process and then dereference a NULL pointe…

> the compiler doesn't know what SIGKILL does, so it doesn't know the UB is unreachable in practice, so it may reorder etc

It is the reverse. If the compiler doesn't know what raise(SIGKILL) (or really, any other function it cannot see through) does, it has to assume that it can potentially never terminate, abort or otherwise change the control flow, so it can't safely reorder across it. And even if it does return, it could still inspect memory and observer the violation of the as-if rule.

That's why for example pthread_mutex_lock/unlock worked correctly for the most part even before C++ got a proper concurrent memory model.

Re: Falsehoods programmers believe about undefined behavior

#224

Earlier quoted context omitted.

That is the observed behavior of the compiler not the defined behavior. (and while there’s some logical reason to assume that will likely continue to hold, the list is falsehoods programmers believe about undefined behavior, not observed behavior.)

(Post author here.) Agreed with the parent comment. To restate the same thing in another way in the hope of avoiding confusion: It isn't a bug in the compiler if the compiler is non-deterministic in the presence of UB. Such behavior does not violate any guarantee provided by the compiler or language spec. In fact, it's still not a bug if the compiler is non-deterministic, full stop. Many (most?) compilers have non-de…

Determinism is a QoI issue. It is an important QoI feature though and I think most compilers meant for production use at least strive to implement it. I guess things like parallel, distributed compilation make it quite hard.

Re: Falsehoods programmers believe about undefined behavior

#225
post #23

Earlier quoted context omitted.

The C specification doesn't say anything about what a compiler may or may not do during compilation. It only specifies how the compiled program should behave. So, yes, the C specification allows a standard-conforming compiler to erase your disk during compilation. It even allows it to do that if your code doesn't contain UB.

What if the UB is in constexpr function used during the compilation?

UB during constexpr evaluation at actual compile time is promoted to ill defined behaviour requiring a diagnostic.

Re: Falsehoods programmers believe about undefined behavior

#226

Earlier quoted context omitted.

I just tested " " in VoiceOver on Mac and nothing gets read. Different screen readers are notoriously inconsistent though. > I wish there were a best practices doc + a matching linter for accessibility things like this. This sounds like it was meant to be a fun tweak/joke for screen readers but it's accessible without. So it's not practical to automate a lot of accessibility checks like this one because it depends on…

> Different screen readers are notoriously inconsistent though. In other words, UB!

Implementation defined

Re: Falsehoods programmers believe about undefined behavior

#227

Earlier quoted context omitted.

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.

On C UB is a property of any code, reachable or not, just like the article's references explain.

Why are people fighting this?

And yes, Rust is much more reasonable about it.

Re: Falsehoods programmers believe about undefined behavior

#228

Earlier quoted context omitted.

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.

On C UB is a property of any code, reachable or not, just like the article's references explain. Why are people fighting this? And yes, Rust is much more reasonable about it.

How do you decide if i+1 is UB or not, unless the abstract machine reaches that line with a given value of i?

Re: Falsehoods programmers believe about undefined behavior

#229

Earlier quoted context omitted.

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

Both "UB" and "IB" are terms defined in the language standards, and it's obvious that's what we're talking about here. x86 defines what specific instructions do, nothing so crass as "signed integer overflow" - that's part of why the language standard has to define it as such.

> x86 defines what specific instructions do, nothing so crass as "signed integer overflow"

I don't understand what you mean. The x86 standard defines what happens if an `add` instruction is performed and the result overflows, possibly affecting the sign bit (what happens is that the OF flag is set, and the target register is set to the two's complement representation of the sum modulo 2^bitlength).

Re: Falsehoods programmers believe about undefined behavior

#230
post #153

Earlier quoted context omitted.

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

Sounds like we shouldn't use memcpy on structs containing padding!

No, memcpy is fine because it's a language level function. What you _can't_ do is implement your own memcpy alternative safely.
Post reply on HN