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…
Falsehoods programmers believe about undefined behavior
71–80 of 233 posts
Re: Falsehoods programmers believe about undefined behavior
#72Earlier quoted context omitted.
You have to understand that in the modern understanding of UB as applied by compiler writers, the compiler has every right to assume the program never triggers UB. This means that lines which would be UB if a variable had certain values can be used as proof that the variable doesn't have those values, thereby eliminating checks. For example, if a program looks like this: void foo(int* const p) { if (p!=NULL) { bar(p)…
Can you just check, I don't think the line *p=1 will even compile given the definition of p
Re: Falsehoods programmers believe about undefined behavior
#73Earlier quoted context omitted.
> there are better and worse things compilers can do in the presence of UB, and the big one is warning you about it when it possibly can. GCC should add -Wundefined-behaviour flag that will unconditionally print "warning: this program might or not have UB" as the first diagnostic.
It should also warn if there are infinite loops, so the dev can know whether it will ever halt.
Seems pretty viable.
Re: Falsehoods programmers believe about undefined behavior
#74> Undefined behavior: Anything is allowed to happen, and you might no longer have a computer left after it all happens. and > The moment your program contains UB, all bets are off. Does this include that a compiler, when it can prove that a program it compiles contains UB, erase your disk as part of the compilation process? i.e. without you ever running the compiled program.
In practice, it means all bets are off, and yes, depending on your code, you may lose some data.
Re: Falsehoods programmers believe about undefined behavior
#75Earlier quoted context omitted.
You have to understand that in the modern understanding of UB as applied by compiler writers, the compiler has every right to assume the program never triggers UB. This means that lines which would be UB if a variable had certain values can be used as proof that the variable doesn't have those values, thereby eliminating checks. For example, if a program looks like this: void foo(int* const p) { if (p!=NULL) { bar(p)…
I don't think this proves the point, because foo() will not invoke UB unless it is called with a NULL argument. It is true that when foo() is called with a NULL argument, the UB will be realized before bar() has had a chance to run (EDIT: this doesn't actually appear to be true for the given code sample, neither Clang nor GCC elide this NULL check: https://godbolt.org/z/v9v74c3jd , which makes sense as bar() could ca…
The point of those numbered lines was to refer to how people normally think about UB. Someone seeing that function may be tempted to say that it's not UB to call with a NULL value as long as the dereference doesn't happen (say, bar() could call exit() or it could run an infinite loop). What you're saying is exactly what the article is saying: the fact that a line with UB is unreachable in practice doesn't mean that it can't affect your program.
> For C, I think this interpretation is directly contradicted by DR #109: https://www.open-std.org/jtc1/sc22/wg14/docs/rr/dr_109.html
The standard talks about executions in the sense of theoretical executions by the C abstract machine, not actual executions of the compiled binary. I thought the other comment was rendering to the latter notion of execution, but perhaps I was wrong and it was also talking about the former.
Re: Falsehoods programmers believe about undefined behavior
#76I am always amazed by articles like these. This guy thoroughly covers this topic. I cannot say I have ever written anything that ran into or caused undefined behavior. And I have programmed for a long time. Is this just an interesting topic or do people actively push the compiler to see what it will do? Maybe I am a boring/simple programmer. :)
You’ve never had an integer overflow? You’ve never dereferenced a null pointer? I suspect every C programmer invokes undefined behavior in their first 50 hours of writing C.
Re: Falsehoods programmers believe about undefined behavior
#77Earlier quoted context omitted.
UB is typically a property of the execution of a program. A program may bump into UB for one set of inputs, but not for an other set.
That is a misconception. "If any step in a program’s execution has undefined behavior, then the entire execution is without meaning. This is important: it’s not that evaluating (1<<32) has an unpredictable result, but rather that the entire execution of a program that evaluates this expression is meaningless. Also, it’s not that the execution is meaningful up to the point where undefined behavior happens: the bad eff…
"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.
Re: Falsehoods programmers believe about undefined behavior
#78I am always amazed by articles like these. This guy thoroughly covers this topic. I cannot say I have ever written anything that ran into or caused undefined behavior. And I have programmed for a long time. Is this just an interesting topic or do people actively push the compiler to see what it will do? Maybe I am a boring/simple programmer. :)
If during that long time you were writing C or C++, it's very likely that you did but you may not have attributed the bugs you were fixing to Undefined Behavior. You may have considered them either to be your bugs or "compiler bugs that you worked around."
Re: Falsehoods programmers believe about undefined behavior
#79Earlier quoted context omitted.
No it doesn't. Modern processors do out-of-order execution, so your program might be doing UB before you expect.
No, no, no. UB is a global property of your program. "All bets are off" even at compile time. "Anything at all can happen; the Standard imposes no requirements. The program may fail to compile, or it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended." https://blog.regehr.org/archives/213
int main(int argc, char **argv) {
int a = atoi(argv[1]);
int b = atoi(argv[2]);
return a + b;
}
contains signed integer overflow in some executions but not others. Can you explain what effect the counterfactual signed integer overflow is allowed to have in executions that do not contain signed integer overflow?Re: Falsehoods programmers believe about undefined behavior
#80Unfortunately this article doesn't refer to the best tool to root out UB - UBSan. If you write C or C++, you should have a UBSan+ASan build that is configured to terminate with an error when it encounters violations. You'll save yourself a lot of hair-pulling later. Then you don't have to wonder about the nebulous topics like what "line" the UB "happened" on.
For some compilers, when they add an optimization that capitalizes on an aspect of UB, they will also add a corresponding warning. So make sure you have warnings enabled -- and in most cases you'll want -Werror because generally no one scrutinizes the build output unless there's a failure.