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++.
Falsehoods programmers believe about undefined behavior
191–200 of 233 posts
Re: Falsehoods programmers believe about undefined behavior
#192Earlier quoted context omitted.
> An infinite loop is not UB. It is well defined. From C11: > An iteration statement whose controlling expression is not a constant expression,156) that performs no input/output operations, does not access volatile objects, and performs no synchronization or atomic operations in its body, controlling expression, or (in the case of a for statement) its expression-3, may be assumed by the implementation to terminate.15…
Not particularly. It does not allow the compiler to assume true infinite loops can terminate. It only allows the compiler to assume loops with non-constant expressions can terminate. (And a bunch of other exceptions where it cannot.) A true infinite loop has a constant expression as the conditional and cannot be optimized away based on this rule. What this rule allows the compiler to do is to optimize away loops wher…
That is basically what I said: loops can be assumed to terminate, except for an enumerated set of exceptions where infinite loops are allowed.
You seem to be defining "true infinite loop" to mean "while(1)" or "for(;;)" exclusively. But "for (int i = 0; i > What this rule allows the compiler to do is to optimize away loops where number of iterations are known ahead of time if it has a non-constant expression condition.
If the number of iterations are known ahead of time, then it is not an infinite loop so I don't see how the rule would apply.
The rationale for making infinite loops UB is described here: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1528.htm
Specifically, it allows for transformations like turning:
for (p = q; p != 0; p = p -> next) {
++count;
}
for (p = q; p != 0; p = p -> next) {
++count2;
}
into: for (p = q; p != 0; p = p -> next) {
++count;
++count2;
}Re: Falsehoods programmers believe about undefined behavior
#193Earlier 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.
You are indeed correct. I would add that there are some instances of UB that actually UB at translation time: for example ODR violations and some preprocessor dark corners. At least the latter is getting stamped out.
Re: Falsehoods programmers believe about undefined behavior
#194Earlier quoted context omitted.
Can someone with more knowledge chip in? If I define void bar(int* const p, int n) { for (int i=0; i it might get optimized via loop-invariant code motion to void bar(int* const p, int n) { int m = *p for (int i=0; i so it could still be UB when called with p=NULL and n=0, right? Edit: Oops, in the previous version I used a write instead of a read on *p, making the optimization invalid.
The first form has no undefined behavior. Since p may be NULL, in general the compiler is not allowed to make that transformation unless it can prove bar never gets called with p=NULL and n=0 (which it probably can't). If the compiler has some special knowledge of the target architecture which makes the second form behave as if the first form was executed (such as if NULL is a valid address on the target architecture…
Re: Falsehoods programmers believe about undefined behavior
#195I 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…
Re: Falsehoods programmers believe about undefined behavior
#196> 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.
This [0] is the linked article for that point, I don’t do systems programming, so I can’t say I understand if this is trivial or not ;) [0]: https://www.ralfj.de/blog/2020/07/15/unused-data.html
> The Rust compiler has a few assumptions that it makes about the behavior of all code. Violations of those assumptions are referred to as Undefined Behavior.
Then it says
> In other words, even just constructing, for example, an invalid bool, is Undefined Behavior—no matter whether that bool is ever actually “used” by the program.
The blog post is talking about how just creating an invalid/trap/niche representation for a value is UB. The act of creating the value is the UB here, not the usage. So, in this case the UB is most definetely reachable and executing (The act of creating the invalid value).
Re: Falsehoods programmers believe about undefined behavior
#197I 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…
Suggestions like this are unfortunately quite infeasible (they fall under the hat of "define all the behaviors"), and the talk I linked in the post goes into why: https://www.youtube.com/watch?v=yG1OZ69H_-o (I'm the post's author.)
Re: Falsehoods programmers believe about undefined behavior
#198Earlier quoted context omitted.
Not particularly. It does not allow the compiler to assume true infinite loops can terminate. It only allows the compiler to assume loops with non-constant expressions can terminate. (And a bunch of other exceptions where it cannot.) A true infinite loop has a constant expression as the conditional and cannot be optimized away based on this rule. What this rule allows the compiler to do is to optimize away loops wher…
> It only allows the compiler to assume loops with non-constant expressions can terminate. (And a bunch of other exceptions where it cannot.) That is basically what I said: loops can be assumed to terminate, except for an enumerated set of exceptions where infinite loops are allowed. You seem to be defining "true infinite loop" to mean "while(1)" or "for(;;)" exclusively. But "for (int i = 0; i > What this rule allow…
for (;;) { }; cannot be assumed to have finite number of executions. Therefore, it cannot be optimized away to finite execution.
You're showing potentially infinite loops with non-constant expression as condition.
for (; i != 0; ) {} can be assumed to have finite number of executions and can be optimized unless i is constant expression.
Re: Falsehoods programmers believe about undefined behavior
#199Earlier 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++.
“An iteration statement that performs no input/output operations, does not access volatile objects, and performs no synchronization or atomic operations in its body, controlling expression, or (in the case of a for statement) its expression-3, may be assumed by the implementation to terminate.”
Rationale for including that: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1528.htm (basically, without it compilers can’t optimize loops that terminate as well as with it)
Re: Falsehoods programmers believe about undefined behavior
#200Earlier quoted context omitted.
This is all fine and dandy, but UBSan and ASan are memory hogs that just won't fit in my single digit MB microcontroller. So the only way to run them is too use an emulator, and that means I cannot sanitize drivers.
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).
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.