Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between loop and while true?

Tags:

loops

rust

The Rust tutorial, and now book claim there is a difference between while true and loop, but that it isn't super important to understand at this stage.

If you need an infinite loop, you may be tempted to write this:

while true {

However, Rust has a dedicated keyword, loop, to handle this case:

loop {

Rust's control-flow analysis treats this construct differently than a while true, since we know that it will always loop. The details of what that means aren't super important to understand at this stage, but in general, the more information we can give to the compiler, the better it can do with safety and code generation, so you should always prefer loop when you plan to loop infinitely.

Having done a little bit of compiler-type work, I have to wonder what possible semantic difference there is, since it would be trivial for the compiler to figure out both are an infinite loop.

So, how does the compiler treat them differently?

like image 254
aij Avatar asked Mar 06 '15 04:03

aij


People also ask

Is while true a loop?

The "while true" loop in python runs without any conditions until the break statement executes inside the loop. To run a statement if a python while loop fails, the programmer can implement a python "while" with else loop.

What is the meaning of while true?

while True means loop forever. The while statement takes an expression and executes the loop body while the expression evaluates to (boolean) "true". True always evaluates to boolean "true" and thus executes the loop body indefinitely.

What is difference between true loop and false loop?

while loops use only Boolean expression and when it is true. So when it gets true it'll execute until it gets false. while(false) means the condition is false which will end the loop. while(True) means the condition is True which will continue the loop.

Do while loop true or false?

It's always true, it's never false. Some people use while(true) loops and then use break to exit them when a certain condition is true, but it's generally quite sloppy practice and not recommended. Without the use of break , return , System. exit() , or some other such mechanism, it will keep looping forever.


3 Answers

This was answered on Reddit. As you said, the compiler could special-case while true, but it doesn't. Since it doesn't, the compiler doesn't semantically infer that an undeclared variable that's set inside a while true loop must always be initialized if you break out of the loop, while it does for a loop loop:

It also helps the compiler reason about the loops, for example

let x;
loop { x = 1; break; }
println!("{}", x)

is perfectly valid, while

let x;
while true { x = 1; break; }
println!("{}", x);

fails to compile with "use of possibly uninitialised variable" pointing to the x in the println. In the second case, the compiler is not detecting that the body of the loop will always run at least once.

(Of course, we could special case the construct while true to act like loop does now. I believe this is what Java does.)

like image 171
telotortium Avatar answered Oct 11 '22 05:10

telotortium


One major difference is that loop can return a value by passing a value to break. while and for will not:

fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    assert_eq!(result, 20);
}
like image 42
user2859458 Avatar answered Oct 11 '22 06:10

user2859458


The first thing to say is, in terms of performance, these are likely to be identical. While Rust itself doesn't do anything special with while true, LLVM likely does make that optimisation. The Rust compiler tries to keep things simple by delegating optimisations to LLVM where it can.

in general, the more information we can give to the compiler, the better it can do with safety and code generation

While certain constant expressions might get optimised away by LLVM, the semantics of the language are not altered by whether an expression is constant or not. This is good, because it helps humans reason about code better too.

Just because true is a simple expression, we know it's constant. And so is true != false and [0; 1].len() == 1. But what about num_cpus::get() == 1? I actually don't know if there are some compilation targets where that could be constant, and I shouldn't have to think about it either!

The error in telotortium's example would be more significant when combined with generated code or macros. Imagine a macro which sometimes results in a simple static expression like true == true, but sometimes references a variable or calls a function. Sometimes the compiler is able to ascertain that the loop runs once, but other times it just can't. In Rust right now, the error in that example will always be an error, no matter what code was generated for that condition. No surprises.

like image 5
Peter Hall Avatar answered Oct 11 '22 04:10

Peter Hall