4 ms·
I don't understand your problem. Did you expect your C++ program to get uninterrupted access to the computer? What progression do you think isn't happening ther
by marcosdumay 8d ago
I don't understand your problem. Did you expect your C++ program to get uninterrupted access to the computer? What progression do you think isn't happening there?
I think you are misinterpreting that. That phrase unambiguously says the loop is preserved on the final binary.
- JoshTriplett 8d agoI expect an infinite loop to be compiled into, for instance, a jump instruction jumping to itself. The OS, if there is any, is welcome to interrupt and context switch. I don't expect code that has no function calls at all to have a system call inserted into it.
- marcosdumay 8d agoOk, I get this. The problem is that what you want is completely against the spirit of the entire language. If your point is that C++ should be more like C in general, I can agree with that. But if your point is that C++ should be literal on this specific case, performance be damned, and the rest of it is ok, then no, that's a bad one.
- JoshTriplett 8d agoI was utterly unconvinced that the original infinite-loop UB gave the compiler any important performance optimization, and I'm unconvinced that this is providing useful value to compensate for its surprise. If I wanted a yield in my infinite loop, I'd add one.
- mitxela 7d agoThe original UB was to allow the compiler to merge two loops without proving termination.
- CamperBob2 7d agoWhat difference does it make? If the loop doesn't terminate, it doesn't terminate, which is almost always a bug, except when it's not. If it does terminate, then great, it terminates. Merging a buggy loop with another loop creates... a buggy loop.
- teo_zero 7d agoTake this example: for (i=0;i<n;i++) A[i]=0; for (i=0;i<n;i++) B[i]=0; It can be conveniently transformed into this: for (i=0;i<n;i++) A[i]=B[i]=0; They are exactly equivalent except if the first loop never terminates. Now, the compiler could try to understand if the first loop does or doesn't terminate, and apply or not the optimization accordingly, but Turing tought us that is indeed a hard task! Or it could decide to never apply it, for fear of those rare and usually pathological cases where the first loop doesn't terminate. Or it could decide to apply it by default and accept that in those cases the program does something different than what the source code says. The latter is better known as UB. The third option won, and that's why infinite loops are UB in the standard.
- mitxela 7d agoYou might ask why it's important that the first loop terminates since in this case the extra side effect would just be a dead store - but if the first loop doesn't terminate then it's possible B is an invalid pointer and then accessing it during the first loop is UB when it shouldn't be. Making a nonterminating loop UB is the patch for this. The standard example is a linked list instead of an array because the compiler can't prove it never has a cycle.
- CamperBob2 7d agoThe complaint I have is that for the sake of benchmark wars, UB has been retconned from "The code might not behave the way you want under certain conditions on certain platforms, hopefully you know what you're doing" to "The compiler can do anything it wants, including rickrolling the user." That is no longer undefined behavior in my book. That is defined behavior that just has an unusually-shitty definition. It's all moot anyway given other trends in progress, but... UB, bah humbug. Stop trying to fix problems that no one had. This is why people are clamoring to replace C/C++ with Rust and AI and whatever. The language needed to become more understandable and more predictable in everyday use, and instead it got worse.
- leni536 8d agoA call to a standard library function is still subject to the as if rule. It doesn't have to manifest into a call instruction to a standard library function. Much like memcpy in source code doesn't have to manifest to a call instruction.
- fc417fc802 7d agoMe: I don't expect to be stabbed. You: But you only might be stabbed. It isn't required to happen only permitted.
- leni536 7d agoA bad but conforming implementation of the standard can screw you over on every line of your program.
- ack_complete 7d agoYes, but the compiler does have to preserve any observable behavior produced by the call to the standard library function. Being able to omit this inserted yield() by the as if rule would mean that it isn't observable, which would also mean that the compiler could already add or not add it anywhere as needed without changing the behavior of the program. Which would seemingly make the inserted yield() pointless as it would have no effect.
- leni536 7d agoArguably the only change to program behavior is to performance characteristics on hosted environments. It does not change any observable behavior otherwise. In environments where there are strong forward progress guarantees a busy infinite loop does the same as far as the abstract machine is concerned, as the OS will eventually put the thread to sleep anyway and other threads can make progress. How soon the thread yields is not "observable behavior" (as defined by the standard document).
- rcxdude 7d agoAny program in an OS only gets as much resources allocated to it as the OS allows (OK, in any general-purpose OS written in the past few decades). sched_yield() doesn't actually reduce that allocation in most cases, anyhow: in fact it has a higher chance of increasing the resources that the thread uses spinning in a loop because it's gonna be thrashing the scheduler as well.