3 ms·
Unfortunate. There isn't ever a good reason to have an infinite loop so concerned compilers could have just diagnosed this as a warning.
by account42 14d ago
Unfortunate. There isn't ever a good reason to have an infinite loop so concerned compilers could have just diagnosed this as a warning.
- echoangle 14d agoThe article mentions a use case for that: > What I found is that this is common in embedded and kernel code as a halt-on-error pattern. When a fatal error occurs and there’s no operating system to exit to, you simply stop:
- account42 14d agoLow level code can and should use assembly to get the precise effect they desire in these cases.
- mdspan 14d agoThat would be pretty cumbersome though. If you're targeting N different architectures, you would have to write N different assembly blocks.
- rcxdude 14d agoI shouldn't need to drop to assembly to get an infinite loop that works!
- echoangle 14d agoWhy not just allow infinite loops instead of having me write assembly for it though?
- account42 14d agoBecause a compiler being allowed to assume that a loop always terminates gives it more room to optimize the 99% of loops that aren't supposed to run until the heat death of the universe.
- echoangle 14d agoOr you could just detect while loops with constant condition (like the C standard) and not touch any programs that don't exhibit UB while allowing infinite loops for other use cases at zero runtime cost and negligible compile cost.
- pdonis 14d agoIf this is a genuine use case, I wonder why the language can't just introduce a built-in function for it. For example, std::get_stuck_here(). Then the compiler would know not to optimize this away. The implementation under the hood could still be an infinite loop, but the compiler would not have to guess why it's there.
- sigbottle 14d ago__asm__ __volatile("hlt"); when doing quick and hacky debugging could work
- gpderetta 13d agoone could already add loads off a volatile and portably prevent the loop from being optimized. But there was already a lot of existing embedded code that had this sort of loop, (and more will be written as it is an existing idiom) which the committee wanted to un-break.
- weinzierl 14d agoFor Rust the infinite loop is important enough to have its own keyword.
- kibwen 14d agoThe reason for this is interesting. Loop constructs that you're guaranteed to enter have implications for control flow (in every language, not just Rust). It means that the following program is valid in Rust: let x; // declared, but uninitialized variable loop { // control flow is guaranteed to enter this loop if some_condition() { x = 42; // initialize x break; } } foo(x); // Rust knows that x is initialized as of here in all possible paths In contrast, while loops check their condition before entering, which means the entire loop body might be skipped. Languages which guarantee initialization-before-use might special-case certain conditions for while loops as a hint to the control flow analysis (e.g. Java special-cases `while(true)`), but obviously this doesn't generalize to arbitrary conditions. Interestingly, this all suggest that, in C-like languages, the more natural implementation of an infinite loop should not be `while(true)` nor `for(;;)`, but rather `do {} while(true)`, because do-while are also guaranteed to enter their body (and note that Rust doesn't feature do-while loops).
- tialaramex 13d agoOoh, that's elegant, thanks for sharing
- weinzierl 13d agoI always thought the lack of a do-while loops in Rust was just a random quirk. Apparently not. Thanks for the insight.
- tialaramex 13d agoRust only actually has a single loop, the other loops in Rust are just syntax sugar. Early in compilation the compiler will "de-sugar" a while or for loop into that ordinary infinite loop and so by the time your code is optimised it can't matter how you wrote the loop. This answers the question Matt Godbolt had which caused him to create what would become Compiler Explorer, is a fancy modern for-each loop able to deliver the same perf as my 1970s loop? In Rust the answer is necessarily "Yes" because by the time the backend sees your program they're the same thing. The reason Matt wanted to know is that obviously a for-each loop often has better ergonomics, so if they mean the same thing we should prefer our team to write this - but if they're slower that's a tough question, should we trade performance for clarity? The "Yes" answer that Matt found for C++ and which is baked into Rust means you don't need to make that trade decision, write whatever is easier to understand and maintain.
- sumtechguy 14d ago> There isn't ever a good reason to have an infinite loop That seems to be a very broad statement. For example in a system where interrupts mostly control things this sort of 'do not close the program' could be useful. A guy I worked with had one I never would think of because I do not work in that field. But yeah a warning would probably be useful.
- not_the_fda 14d agoInterrupt driven super loops are very common on bare metal systems.
- mdspan 14d agoCompilers can still diagnose something as a warning even if it's not UB.
- cppcppcpp 13d agoCan, yes. Must, no.
- tialaramex 13d agoWarnings are poisoned in C++. It is popular to tell C++ compilers to convert all their warnings into fatal errors. So your only options are "Silently allow probably bad code" and "Program does not compile" because C++ programmers are allergic to nuance.
- anticensor 12d agoOh you mean the -Wall -Werror crowd.