3

I am playing around a little with for loops , tried the following code and got an infinite loop.

#include<iostream>

int main(){
       int i {0};
       bool condition = i < 5;
       for ( ; condition ; ){
              std::cout << "Hello World!" << std::endl;
              i++;  
       }
}  

Can someone explain why ?

Ken Za
  • 81
  • 6

4 Answers4

9
bool condition = i < 5;

This line defines a variable named condition which has the value true from this line onwards.

It does not bind the expression from the right side, but only copies the result at the time of assignment.

What you intended is more complicated:

auto condition = [&i](){ return i < 5; };
for ( ; condition() ; )

Now condition is a function object which can be evaluated repeatedly.

The right hand of the assignment is called a lambda expression, and follows the form [capture scope](parameters){ body with return statement }.

In the capture scope, you can list variables either by value (without &) in which case they get copied once when the lambda is declared, or by reference (with leading &) in which case they don't get copied but the variable inside the lambda is a reference to the variable of the same name outside the lambda. There is also the short form [&] which captures all variables in the parent scope by reference, and [=] which captures everything by value.

auto can be used for brevity in combined declarations + assignments, and automatically resolves the type of the variable from the right hand side.

The closest compatible type you could explicitly specify would be std::function<bool(void)> (generic container for functions with that signature), the actual type of that object is some internal type representing the naked lambda which you can't write explicitly. So if you can't know the exact type, and you don't want to use a generic container type, auto is occasionally even necessary.

Ext3h
  • 5,713
  • 17
  • 43
  • can you explain the auto line a little bit – Ken Za Nov 11 '21 at 11:15
  • @KenZa `auto` means that, if possible, let C++ infer the type "auto"matically :) the value of condition is a lambda - an anonymous (nameless) function that can be assigned to a variable, in this case `condition`. Its type will be inferred as `bool` from the lambda definition. – Josh Greifer Nov 11 '21 at 11:16
  • @JoshGreifer i know 'auto' , i meant the entire line , from what i understand 'return i < 5' updates the value of the boolean and the '[&i]' thing changes the value of i by reference ? – Ken Za Nov 11 '21 at 11:19
  • Almost: The function doesn't change the value of `i`, but it does "refer" to it each time it's called. – Josh Greifer Nov 11 '21 at 11:22
  • @JoshGreifer actually now that i look at it , i see it as a function called `condition` which returns a `boolean` but we haven't passed an int as a parameter , so maybe `[&i]` is a method of doing so but i don't know about it – Ken Za Nov 11 '21 at 11:43
  • @JoshGreifer like instead of `boolean condition ( int ) {return i<5;}` and putting `condition(i)` in the `for` loop – Ken Za Nov 11 '21 at 11:44
  • @Ext3h i just saw the edits, can you explain the `[&i]` please – Ken Za Nov 11 '21 at 11:48
  • 1
    @KenZa It is the capture block for the closure, it says it captures the identifier `i` by reference. See [What is a lambda expression in C++11?](https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11). – François Andrieux Dec 13 '21 at 15:07
3

Variables in C++ store values. You seem to be under the impression that condition somehow remains connected to the expression i < 5. It is not. Once you set the value which is true at the time of the assignment it will keep that value until you change it. You never change it again so the value of condition is forever true.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • yeah true , i re-wrote the definition of 'condition' now inside the loop and it works perfectly fine, thanks a lot . By the way i just had a problem with debugging multiple files , wonder if you can help me with it ? – Ken Za Nov 11 '21 at 11:10
2

citing cppref:

Executes init-statement once, then executes statement and iteration-expression repeatedly, until the value of condition becomes false. The test takes place before each iteration.

Now, your condition evaluates to true:

bool condition = i < 5; // true

hence, the loop will continue until false, which does not happen in the loop body of your code; condition is not written to after initialization, and therefore the loop will not stop.

Andreas DM
  • 10,685
  • 6
  • 35
  • 62
1

The for loop runs on a condition, such as while i is below a specified value, and will keep running until this is no longer satisfied. In your case, it is never satisfied, guaranteeing an infinite loop.

Larry the Llama
  • 958
  • 3
  • 13
  • @LarrytheLIama why is the condition never satisfied ? i am incrementing the value of i every time so when it hits 5 the boolean normally would be false so the for loop should stop , no ? – Ken Za Nov 11 '21 at 11:02
  • 2
    You are not continually updating the condition, only to begin with at the start (when i is 0). – Larry the Llama Nov 11 '21 at 11:06
  • @LarrytheLIama yes i added condition inside the loop and it works now – Ken Za Nov 11 '21 at 11:11