t is initialized to 0, t == 5 will always be evaluated to be false, so your for loop will never run.

update

for (t = 0; t == 5; t++) {

to

for (t = 0; t < 5; t++) {

for Statement

Executes a statement repeatedly until the condition becomes false.

for ( init-expression ; cond-expression ; loop-expression )

      statement;
Answer from billz on Stack Overflow
🌐
cppreference.com
en.cppreference.com › cpp › language › for
for loop - cppreference.com
Conditionally executes a statement repeatedly, where the statement does not need to manage the loop condition. ... A condition can either be an expression or a simple declaration. If it can be syntactically resolved as an expression, it is treated as an expression.
🌐
Florida A&M University
web1.eng.famu.fsu.edu › ~haik › met.dir › hcpp.dir › notes.dir › cppnotes › node45.html
for Loop
You can have any number of initialization and increment statements, but in practice, limit yourself to two or three. The condition controlling the loop may be any valid C++ expression. Another aspect for the for loop that is different in C++ than in many computer languages is that pieces of the loop definition need not be there.
Discussions

c++ for loop does not work
How is the function being called? What does "does not work" mean? Do you have a compilation error? If so, what is it? Does the program crash? Hang? Does the program give the wrong results? If so, what is the data, what results are you expecting, and what results do you get? More on reddit.com
🌐 r/Cplusplus
21
0
October 26, 2022
c++ - while loop requires explicit condition, for loop doesn't, why? - Stack Overflow
This answers why for(;;) is valid, but does not address why while() cannot be (which likely would be opinion based). 2014-02-11T21:06:47Z+00:00 ... The point is that they didn't set out to make conditions optional in control statements in general. It was purely a matter of consistency within the special case of the for-loop. 2014-02-11T21:17:46.64Z+00:00 ... @ZacHowland the only reason to make while() work without a condition would be to express ... More on stackoverflow.com
🌐 stackoverflow.com
c++ - Why isn't a for-loop a compile-time expression? - Stack Overflow
But the same argument could then be used for just about any construct, not just for loops. ... The statement std::get(t); has no effect. Once you put sensible code in there, the problems with your proposal ought to become a lot clearer. ... The idea behind a a compile-time expression is that ... More on stackoverflow.com
🌐 stackoverflow.com
for loop bugs

The problem is that you put 2 statements in the first part of the for loop. A for loop goes like this:

for( initialization ; condition ; update)

Where initialization, condition, and update are all individually a valid line of code. int i = 0, int num = strlen(text); is not a valid line of code. You can make several declarations on one single line, but only one type can be specified. In this case, simply removing the secont int, before num, would fix that problem.

More on reddit.com
🌐 r/cs50
5
1
September 15, 2014
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › cpp-loops
Loops in C++ - GeeksforGeeks
An infinite loop (sometimes called an endless loop) is a piece of code that lacks a functional exit so that it repeats indefinitely. An infinite loop occurs when a condition is always evaluated to be true. Usually, this is an error.
Published   1 week ago
Top answer
1 of 6
22

Here's a way to do it that does not need too much boilerplate, inspired from http://stackoverflow.com/a/26902803/1495627 :

template<std::size_t N>
struct num { static const constexpr auto value = N; };

template <class F, std::size_t... Is>
void for_(F func, std::index_sequence<Is...>)
{
  using expander = int[];
  (void)expander{0, ((void)func(num<Is>{}), 0)...};
}

template <std::size_t N, typename F>
void for_(F func)
{
  for_(func, std::make_index_sequence<N>());
}

Then you can do :

for_<N>([&] (auto i) {      
  std::get<i.value>(t); // do stuff
});

If you have a C++17 compiler accessible, it can be simplified to

template <class F, std::size_t... Is>
void for_(F func, std::index_sequence<Is...>)
{
  (func(num<Is>{}), ...);
}
2 of 6
19

πάντα ῥεῖ gave a good and useful answer, I would like to mention another issue though with constexpr for.

In C++, at the most fundamental level, all expressions have a type which can be determined statically (at compile-time). There are things like RTTI and boost::any of course, but they are built on top of this framework, and the static type of an expression is an important concept for understanding some of the rules in the standard.

Suppose that you can iterate over a heterogenous container using a fancy for syntax, like this maybe:

std::tuple<int, float, std::string> my_tuple;
for (const auto & x : my_tuple) {
  f(x);
}

Here, f is some overloaded function. Clearly, the intended meaning of this is to call different overloads of f for each of the types in the tuple. What this really means is that in the expression f(x), overload resolution has to run three different times. If we play by the current rules of C++, the only way this can make sense is if we basically unroll the loop into three different loop bodies, before we try to figure out what the types of the expressions are.

What if the code is actually

for (const auto & x : my_tuple) {
  auto y = f(x);
}

auto is not magic, it doesn't mean "no type info", it means, "deduce the type, please, compiler". But clearly, there really need to be three different types of y in general.

On the other hand, there are tricky issues with this kind of thing -- in C++ the parser needs to be able to know what names are types and what names are templates in order to correctly parse the language. Can the parser be modified to do some loop unrolling of constexpr for loops before all the types are resolved? I don't know but I think it might be nontrivial. Maybe there is a better way...

To avoid this issue, in current versions of C++, people use the visitor pattern. The idea is that you will have an overloaded function or function object and it will be applied to each element of the sequence. Then each overload has its own "body" so there's no ambiguity as to the types or meanings of the variables in them. There are libraries like boost::fusion or boost::hana that let you do iteration over heterogenous sequences using a given vistior -- you would use their mechanism instead of a for-loop.

If you could do constexpr for with just ints, e.g.

for (constexpr i = 0; i < 10; ++i) { ... }

this raises the same difficulty as heterogenous for loop. If you can use i as a template parameter inside the body, then you can make variables that refer to different types in different runs of the loop body, and then it's not clear what the static types of the expressions should be.

So, I'm not sure, but I think there may be some nontrivial technical issues associated with actually adding a constexpr for feature to the language. The visitor pattern / the planned reflection features may end up being less of a headache IMO... who knows.


Let me give another example I just thought of that shows the difficulty involved.

In normal C++, the compiler knows the static type of every variable on the stack, and so it can compute the layout of the stack frame for that function.

You can be sure that the address of a local variable won't change while the function is executing. For instance,

std::array<int, 3> a{{1,2,3}};
for (int i = 0; i < 3; ++i) {
    auto x = a[i];
    int y = 15;
    std::cout << &y << std::endl;
}

In this code, y is a local variable in the body of a for loop. It has a well-defined address throughout this function, and the address printed by the compiler will be the same each time.

What should be the behavior of similar code with constexpr for?

std::tuple<int, long double, std::string> a{};
for (int i = 0; i < 3; ++i) {
    auto x = std::get<i>(a);
    int y = 15;
    std::cout << &y << std::endl;
}

The point is that the type of x is deduced differently in each pass through the loop -- since it has a different type, it may have different size and alignment on the stack. Since y comes after it on the stack, that means that y might change its address on different runs of the loop -- right?

What should be the behavior if a pointer to y is taken in one pass through the loop, and then dereferenced in a later pass? Should it be undefined behavior, even though it would probably be legal in the similar "no-constexpr for" code with std::array showed above?

Should the address of y not be allowed to change? Should the compiler have to pad the address of y so that the largest of the types in the tuple can be accommodated before y? Does that mean that the compiler can't simply unroll the loops and start generating code, but must unroll every instance of the loop before-hand, then collect all of the type information from each of the N instantiations and then find a satisfactory layout?

I think you are better off just using a pack expansion, it's a lot more clear how it is supposed to be implemented by the compiler, and how efficient it's going to be at compile and run time.

Find elsewhere
🌐
Tutorialspoint
tutorialspoint.com › cplusplus › cpp_loop_types.htm
C++ Loop Types
A loop becomes infinite loop if a condition never becomes false. The for loop is traditionally used for this purpose. Since none of the three expressions that form the for loop are required, you can make an endless loop by leaving the conditional expression empty.
🌐
Quora
quora.com › How-do-I-put-a-loop-in-the-if-statement-condition-in-C
How to put a loop in the if statement condition in C++ - Quora
No, because the standard says the if construct is of the type: “if ( <expression> ) <statement>”. A while loop is not an expression, so its not allowed.
🌐
Codecademy
codecademy.com › article › cpp-for-loop
What is a for Loop in C++? | Codecademy
Learn how to use a `for` loop in C++ with syntax, examples, and use cases. Understand nested and range-based `for` loops and their real-world applications.
🌐
Cppreference
en.cppreference.com › w › cpp › language › range-for.html
Range-based for loop (since C++11) - cppreference.com
June 20, 2024 - The member interpretation is used if the range type has a member named “begin” and a member named “end”. This is done regardless of whether the member is a type, data member, function, or enumerator, and regardless of its accessibility. Thus a class like class meow { enum { begin = 1, end = 2 }; /* rest of class */ }; cannot be used with the range-based for loop even if the namespace-scope “begin”/“end” functions are present. While the variable declared in the item-declaration is usually used in the statement, doing so is not required.
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › cpp-for-loop
for Loop in C++ - GeeksforGeeks
If true then it prints the value of i followed by a space and decrement i. When the condition is false loop terminates. Notice that we have not used braces {} in the body of the loop.
Published   March 31, 2026
🌐
Reddit
reddit.com › r/cs50 › for loop bugs
r/cs50 on Reddit: for loop bugs
September 15, 2014 -
    anyone explain these errors?           


    int num = 0;
    for (int i = 0, int num = strlen(text); i < num; i++)

    errors... 
       file.c:28:23: error: expected identifier or '('
   for (int i = 0, int num = strlen(text); i < num; i++)
              ^
   file.c:28:23: error: expected ';' in 'for' statement specifier
  file.c:28:23: error: expected expression
  file.c:28:54: error: expected ')'
 for (int i = 0, int num = strlen(text); i < num; i++)
                                             ^
    file.c:28:11: note: to match this '('
    for (int i = 0, int num = strlen(text); i < num; i++)
        ^
       file.c:28:49: error: expression result unused [-Werror,-Wunused-          value]
      for (int i = 0, int num = strlen(text); i < num; i++)
                                               ~ ^ ~~~
         file.c:28:56: error: use of undeclared identifier 'i'
       for (int i = 0, int num = strlen(text); i < num; i++)
                                                        ^
🌐
W3Schools
w3schools.com › cpp › cpp_for_loop.asp
C++ For Loop
Statement 3 increases a value each time the code block in the loop has been executed: i++ ... int sum = 0; for (int i = 1; i <= 5; i++) { sum = sum + i; } cout << "Sum is " << sum; Try it Yourself » ... If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: sales@w3schools.com
🌐
Cplusplus
cplusplus.com › doc › tutorial › control
Statements and flow control
Because each of the fields is executed ... initialization, condition, or statement. Unfortunately, these are not statements, but rather, simple expressions, and thus cannot be replaced by a block....
🌐
cppreference.com
en.cppreference.com › cpp › language › while
while loop - cppreference.com
July 22, 2024 - If it can be syntactically resolved as an expression, it is treated as an expression. Otherwise, it is treated as a declaration that is not a structured binding declaration(since C++26).
🌐
Weber State University
icarus.cs.weber.edu › ~dab › cs1410 › textbook › 3.Control › for.html
3.5.1. For-Loops
The update statement, highlighted in yellow, increments the loop control variable by two during each iteration. So, this loop iterates over even, non-negative values from 0 to 8. An easy error is to use i+2 in place of the highlighted statement, but that expression doesn't change i, and the loop doesn't work.
🌐
Quora
quora.com › How-can-a-for-loop-be-written-without-an-incrementer-in-C
How can a for loop be written without an incrementer in C++? - Quora
Answer (1 of 2): The for loop has three “clauses” ( clauses not being an official term.) An initializer. A condition. And a final expression. They are all optional. You can literally write: for (;;) // Effectively, a do forever loop There’s few restrictions on these clauses.