Live data from Hacker News

Falsehoods programmers believe about undefined behavior

predr.ag

161–170 of 233 posts

Re: Falsehoods programmers believe about undefined behavior

#161

> 14. Okay, but if the line with UB is unreachable (dead) code, then it's as if the UB wasn't there. This one came as a surprise to me. Is this really (unconditionally) true? And if so, why? Seems trivial to me to ensure that UB that will never under any circumstance execute will not affect the functioning of an otherwise correct program.

That (or more general 13-16) also does not make sense to me. Most UB (although perhaps not all, so it may be true for some obscure UB, or ones with constant arguments) are undefined for specific dynamic conditions, so it is not 'line with UB' but more 'line with UB under specific program state', e.g. expression 'a / b;' has UB if b == 0, 'a->item' has UB if b == NULL, or 'a * 4' has UB if a is int and large enough to…

FYI, an ODR violation (https://en.wikipedia.org/wiki/One_Definition_Rule) is an example of non-dynamic UB.

Re: Falsehoods programmers believe about undefined behavior

#162
post #154

I have another falsehood: most programmers believe that people working with C/C++ are constantly battling against UB all day long, five days a week, and that they are irresponsable and careless. That they should live in fear and terror, because "unsafe" is around the corner, and that their programs are not mathematically proven and that they might containt an explotaible bug because, you know, every other C/C++ progr…

An automobile recall is a good analogy here. Most people driving cars with an active recall are unaffected by the problem the recall is supposed to address. They can drive on blissfully unaware that something could go wrong. They might even enthusiastically recommend that others purchase the car they drive. For a few people, they'll experience a failure, possibly a dangerous one. And this is the root of the problem.…

The same applies to vaccines and medicine drugs. Should we stop giving them to people? "For a few people, they'll experience a failure, possibly a dangerous one.".

Should we try our best to minimize the risks? Absolutely. But we are talking programs here. We shouldn't measure every program with the same ruler. Not all programs need to be MISRA compliant when they don't need to.

My Reddit app crashes several times a day, and I guess there is no immediate danger.

Re: Falsehoods programmers believe about undefined behavior

#163
post #77

Earlier quoted context omitted.

I agree, but this doesn't refute what I wrote. "If any step in a program’s execution has undefined behavior, then the entire execution is without meaning..." Yes. So UB is a property of a given execition, not a static property of the program itself. I don't argue that you can reason about the behavior of any part of the execution, once it evaluates operations with UB.

once and before . If a given execution would eventually lead to UB, then it retroactively it cannot be reasoned about. This time traveling behavior is what is confusing people in thinking that if any execution is UB then all possible executions are UB.

I think this hits the nail on the head.

Many people in this thread are confused and think that unreachable UB (either statically or dynamically unreachable) compromises the entire program. This is not true, but your comment helps me better understand how people reached this conclusion.

Reachable UB (either provably reached at compile time or dynamically reached at runtime) can retroactively invalidate the correctness of previous statements. But this does not mean that unreachable UB compromises the correctness of well-defined executions.

Re: Falsehoods programmers believe about undefined behavior

#164
post #6

The biggest problem with UB, as interpreted by C/C++ compilers is the unfounded belief that the spec says that you can assume any path that leads to UB is defacto incorrect and can be ignored. That's the bogus logic required for steps 13-16 to be true. That interpretation of the specification language is clearly bogus as that means more or less all C and C++ programs can be compiled to a single return instruction - w…

This is a necessary consequence (in the formal logic sense) of the "principle of explosion"[1] for optimizing compilers. If the compiler assumes some undefined behavior does not occur, but in fact that undefined behavior does occur, all of conclusions it makes which depend, directly or indirectly, on the contradicted assumption are invalid.

Since, in the process of optimization, optimizing compilers make conclusions about parts of a program based on other parts of the program which may be executed later, undefined behavior in one part of a program causes invalid conclusions about other parts which may be executed earlier. Therefore undefined behavior cannot be contained to just parts of a program executed after a particular part, if the compiler tries to optimize parts of the program based on parts that may be executed later.

[1]: https://en.wikipedia.org/wiki/Principle_of_explosion

Re: Falsehoods programmers believe about undefined behavior

#165

Earlier quoted context omitted.

Nope, the C spec is just really bad. The NULL check is allowed to be removed.

So the pseudocode: if (p is not NULL) { dereference p } is UB? That's crazy, but not actually unbelievable.

The poster is just completely wrong. A compiler is required to emit the branch in this case.

Re: Falsehoods programmers believe about undefined behavior

#166
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.

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

Re: Falsehoods programmers believe about undefined behavior

#167

I have a suggestion - it may be completely off the wall, but hear me out. C needs a mechanism to declare in a source file that certain behaviour must be defined, where that behaviour is undefined in the C standard but the target architecture behaves the defined way. Then, when the source is compiled on the target architecture it works as expected, but when compiled on something else it refuses to compile. For example…

Ada already does something like this. You can choose whether to enable runtime checks, fail to compile, or accept the risk. The purpose of C is to be easy to implement on new systems. You're never going to get a lot of traction adding anything to C proper.

> Ada already does something like this. You can choose whether to enable runtime checks, fail to compile, or accept the risk.

It is ok, the accelerometer readings won't go outside the range of an int.

Re: Falsehoods programmers believe about undefined behavior

#168

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.

You need to actually invoke at compile time your constexpr function with the specific arguments that would cause UB to actually get an error. It is not significantly better than running your test cases with with UBsan but it is a nice feature.

Good point. Also UBsan and Asan are great additions to any C/C++ workflow. But if it's actually part of the code, I'm forced to use it even if I'm lazy, versus an external tool that I can forget to run (or forget to add to my build system).

Leveraging what the compiler gives you is like that saying "the best camera is the one you have on you".

Re: Falsehoods programmers believe about undefined behavior

#169

It is not explained why points 31 to 36 are valid, unlike HDL synthesis tools, C compilers are pretty deterministic, same input same output, except timestamps, etc. If an UB adopt X behavior one time, a reproducible build will take same X behavior the next time. Of course I am not negating the fact that this undefined in the first instance nor condoning the UB usage.

I was curious about that as well. If it is just an extension of 37-40, then that makes sense - since UB may or may not effect different runs of the same executable, then certainly the same is true of different runs on different builds of the same executable. But that is a confusing way to put it - it sounds like it is saying that reproducible builds are not possible, which I am skeptical of.

Re: Falsehoods programmers believe about undefined behavior

#170

Earlier quoted context omitted.

You need to actually invoke at compile time your constexpr function with the specific arguments that would cause UB to actually get an error. It is not significantly better than running your test cases with with UBsan but it is a nice feature.

Good point. Also UBsan and Asan are great additions to any C/C++ workflow. But if it's actually part of the code, I'm forced to use it even if I'm lazy, versus an external tool that I can forget to run (or forget to add to my build system). Leveraging what the compiler gives you is like that saying "the best camera is the one you have on you".

Good point.

I love constexpr because it allows me to write compile time unit tests inline with the library code, with static_assert. The implied UB check is gravy.

Post reply on HN