Home > Blockchain >  Is it advised to declare variables inside loops?
Is it advised to declare variables inside loops?

Time:09-08

As far as I know, declaring a variable inside a loop is less efficient than declaring outside and modify it inside the loop.

Example:

std::list<<double> l;
for(int i = 0; i < 100000;   i)
{
    double a;
    a = 500.0 * i;
    l.append(a);
}

Another example with pointer:

std::list<<double *> l;
for(int i = 0; i < 100000;   i)
{
    double* a;
    *a = 500.0 * i;
    l.append(a);
}

The examples don't have enough sense but I just want to show that the double and the pointer are being declared inside the loop.

The thing is, the scope of the variable is the same as the loop, so when the loop do an iteration, will it destroy the variable and then declaring it again? Or it just stays in the heap until the end of the for loop? How efficient is it to do that? Is it a waste of resources?

I code it as it was in C .

Thanks in advance!

CodePudding user response:

In terms of memory usage, there is no difference in most implementations. A stack frame is typically created to accommodate all variables declared anywhere inside the function.

But if the type has a constructor and/or destructor, there might be additional overhead in calling it every loop iteration. And if that type allocates memory of its own (e.g. std::vector), then those allocations and deallocations are also going to happen each loop iteration, instead of only once.

That said, you should still start out by declaring the variable inside the loop if it's not needed for longer than one iteration! It's easy to forget to clear any previous value, and this can quickly lead to bugs. Much better to make it correct first, and optimize afterwards.

CodePudding user response:

As a general rule, I would say postpone variable definition as long as possible. It will help you to have clean code and also more efficient programs.

But or the case of loops, the story is a little bit different. Suppose that we have two loops like this:

// loop 1 - define variable outside the loop
MyType t;
for(auto x : x_container)
{
   t = DoSthAndGetT(x);
   // the rest of the code
}

// loop 2 - define variable inside the loop
for(auto x : x_container)
{
   MyType t(DoSthAndGetT(x));
   // the rest of the code
}

For loop 1 you have the calls for one constructor, one destructor and n assignments. For loop 2 you have n constructors and n destructors

So, considering the heaviness of your constructor, destructor and assignments, you can decide about the approach to select.

CodePudding user response:

First of all

double* a;
*a = 500.0 * i;

Is outright wrong. It invokes undefined behavior because a is not pointing to a double. Don't write code like this. Don't expect pointers to do magic. Pointers point somewhere, thats what they do. To store a double you need a double, not just a pointer.


Don't be afraid to introduce a temporary double inside a loop. A good compiler will notice that there is absolutely no difference in the end result whether you wrote the code like you did or the code is this:

std::list<double> l;
for(int i = 0; i < 100000;   i)
{
    l.append(500.0 * i);
}

Hence, I would expect the compiler to emit the same output for any of the three versions. See What exactly is the "as-if" rule?.

You should rather write code for clarity and readability.

Do you want to use the same a in each iterator or do you want a different a in each iteration? Thats what decides to declare a inside or outside the loop. You can introduce a scope to limit the scope of a to be as narrow as possible even when declaring it outside of the loop:

 std::list<double> l;
 { 
     double a = 0.0;
     for (int i = 0; i <100000;   i) {
          l.append(a);
          a  = 500.0;
     }
 }
  • Related