Overhead for declaring variables within loop?

When writing a program I know it is best practise to keep the scope of your variables as small as you can.

Is there any additional overhead for declaring/redecalring variables within loop()?

I also thought that doing this might be problematic as you are declaring a variable that already exists on the second iteration anyway?

int somevalue;

void setup() {

}

void loop() {
    somevalue = analogRead(A0)
    int anothervalue = analogRead(A0);
}

you are declaring a variable that already exists on the second iteration anyway?

"somevalue" already exists, "anothervalue" does not

"somevalue" already exists, "anothervalue" does not

Of course, I am forgetting loop is in fact a function called within main.cpp's infinite loop and hence scope is lost on each iteration - sometimes you have to be mindful of the abstractions Arduino has in place!

So to answer my question, is there an overhead in doing this?

Would a static variable typically be preferred to a global variable?

I would say it's pretty obvious loop() is a function. And Arduino doesn't make any difference here. If you would do it directly in a infinite while inside main it's also destroyed every pass

void main(){
  while(true){
    int recreatedEveryPass = 5;
  }
}

And no overhead. The global even takes more program space. Just do a simple test

int test = 5;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print(test);

}

Uses 2088 bytes

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

}

void loop() {
  // put your main code here, to run repeatedly:
  int test = 5;
  Serial.print(test);

}

Uses 2082 bytes.

If you really need it only there then yes, I would say a static is better. But then you can only use it there. (Except when you start to use pointers to it.....)

As true today as it was in 1974...

[url=http://web.archive.org/web/20130731202547/http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf]Structured Programming with go to Statements - DONALD E. KNUTH[/url]: There is no doubt that the grail of efficiency leads to abuse. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: pre-mature optimization is the root of all evil.

In other words, @CatsLoveJazz, you are concerned about something that is irrelevant until there is a context.

I was actually thinking that creating a new variable might have additional overhead compared with using an existing variable - but I'm assuming by your answer this is not the case?

If you would do it directly in a infinite while inside main it's also destroyed every pass

So does this mean the compiler treats these two situations differently:

  while(true){
    int recreatedEveryPass = 5;
  }
    int created = 5;
    int created = 5;

I wasn't necessarily looking to super-optimize my code, just understand what was going on under the hood. Thanks for the feedback guys, to add another quote from Donald Knuth:

premature optimization is the root of all evil

CatsLoveJazz:
So does this mean the compiler treats these two situations differently:

The snippets lack context. Without that there is no way to know.

For example, the first snippet, as presented, does not compile. Which makes the answer yes, the compiler does treat them differently.

The second snippet will not compile either.

[quote author=Coding Badly date=1471125550 link=msg=2880542] As true today as it was in 1974...

Quote from: Structured Programming with go to Statements - DONALD E. KNUTH There is no doubt that the grail of efficiency leads to abuse. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: pre-mature optimization is the root of all evil.

[/quote]

How true!!! Even on this forum!

"Wah-wah!! I can't use floating point because it will take an extra microsecond and slow down my program".

"Wah-wah!!! I've got 256K of flash memory, but I've got to keep my program under 12K".

"Wah-wah!!! I want non-blocking delays - even though my code does nothing while it's waiting anyway".

"Wah-wah!!! I've got 8K of SRAM, but I'll put all the strings of my tiny sketch in PROGMEM so I don't run out (while still having 8180 bytes of ram free)".

"Wah-wah!!! I just HAVE to use a dozen Serial.print() calls to build up one string because using stdin and stdout will consume 32 bytes of SRAM and I only have 8000 bytes left!".

.... ad-nauseaum ....

I don’t think the OP was asking the question in the way most are responding. Indeed, his question simply asks if there is additional overhead associated with defining a variable within a loop. To me, all he was asking was: Is a variable defined within a loop reallocated on each pass?

I do agree about context, however. For example:

   for (int i = 0; i < MAX; i++) {
      int answer = myFunction(i);
      // some additional code that uses answer so it's not optimized away...
   }

Variable i doesn’t carry overhead with respect to the for loop because the expression that defines i is only executed once. I think the OP’s question was: Is answer redefined on each pass through the loop. When I read his question, I interpreted it as a question of interest, not efficiency.

Krupski: How true!!! Even on this forum!

"Wah-wah!! I can't use floating point because it will take an extra microsecond and slow down my program".

"Wah-wah!!! I've got 256K of flash memory, but I've got to keep my program under 12K".

"Wah-wah!!! I want non-blocking delays - even though my code does nothing while it's waiting anyway".

"Wah-wah!!! I've got 8K of SRAM, but I'll put all the strings of my tiny sketch in PROGMEM so I don't run out (while still having 8180 bytes of ram free)".

"Wah-wah!!! I just HAVE to use a dozen Serial.print() calls to build up one string because using stdin and stdout will consume 32 bytes of SRAM and I only have 8000 bytes left!".

.... ad-nauseaum ....

Well all the things you mention are obvious optimizations or don't fall into that category (I've not read recommendations by anyone serious here to keep programs under 12k on a 256k architecture) so i don't think they qualify for the tricks Knuth had in mind and if you had read this very old (thanks Coding badly - that brought up some memories) you would have seen that getting those microseconds optimization in inner loops is where you can deliver big wins. The article also states this applies to non IO bound programs and when you have serial involved at high speed and only a 32 or 64 byte buffer then timing matters.

Also many of us like to play with UNO type where you have only 2k of SRAM

My view is use what makes sense for your case indeed and understand the consequences of your choices is what matters.

    int created = 5;
    int created = 5;

Will never compile… Creating two variables in the same scope with the same name…

I agree a question out of curiosity isn’t wrong but it’s also good to point out it’s not very useful. I expanded the example to something that compiles:

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
    for (int i = 0; i < 100; i++) {
      int answer = myFunction(i);
      // some additional code that uses answer so it's not optimized away...
   }

}

int myFunction(int i){
  return i && 0xff;
}

Not global: 450 bytes

int answer;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
    for (int i = 0; i < 100; i++) {
      answer = myFunction(i);
      // some additional code that uses answer so it's not optimized away...
   }

}

int myFunction(int i){
  return i && 0xff;
}

Global: 482 bytes

But I agree for most part with Krupski, don’t try to outsmart the compiler. If you want to outsmart a compiler, write assembly. But you can make some smart choices like using the right variable type (using a long when a byte is okay), avoiding floats (not only because the extra time they take but mainly for there pitfalls) or don’t use delay() in a main program (good for a quick debug but even while the program is doing nothing else now, with a delay() it’s kind of a nightmare to expand it later).

septillion:
But I agree for most part with Krupski, don’t try to outsmart the compiler.

Very true. I took your code and tried to see what the impact might be in a very crude test:

//int answer;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  long start, end;

  start = millis();

  for (int k = 0; k < 30000; k++) {
    for (int i = 0; i < 100; i++) {
      int answer = myFunction(i);
//      answer = myFunction(i);
      if (k % 30000 == 0)
        Serial.print(answer);
      // some additional code that uses answer so it's not optimized away...
    }
  }
  end = millis();
  Serial.print("\nTime: ");
  Serial.println(end - start);
}

int myFunction(int i) {
  return i && 0xff;
}

To make the test even work, I had to “dumb-down” the code because the compiler was smart enough to optimize away do-nothing loops. The version above displays about 2741 milliseconds on my machine and uses 2404 bytes of flash and 208 bytes of SRAM. Commenting out the appropriate lines for answer in the loops and uncommenting the alternative definition for answer as a global results in 4628 milliseconds using 2412 bytes of flash and 210 bytes of SRAM. I was surprised by the magnitude of the difference using the global.

For global variables that don’t variate, #define is worth a look

Thanks @econjack, I had obviously not been clear enough, or lacked the understanding to do so, but my query was intended to be focused on overhead in terms of CPU cycles opposed to memory. So in this test it seems that using a global variable is somewhat slower than creating a new local variable.

I had expected this result might have been the other way around.

CatsLoveJazz: I had expected this result might have been the other way around.

Me too, but I'm glad it seems to work in favor of more-narrowly defined variables, as it adds one more tick mark in favor of data encapsulation.

econjack: Me too, but I'm glad it seems to work in favor of more-narrowly defined variables, as it adds one more tick mark in favor of data encapsulation.

Me two :D Great job econjack!

CatsLoveJazz: but my query was intended to be focused on overhead in terms of CPU cycles opposed to memory.

True, but I talked about program memory, not RAM. Although it's not definitive, the fact a simple, non-looping, program uses more program memory is an indicator it executes more code so more time. It's indeed not water tight because loops will add time without a lot of code so the test of econjack is better :)

INTP: For global variables that don't variate, #define is worth a look

No, please don't! In C++ we have the const keyword which leaves all the room for the compiler to optimize. Macros still have there place but are cool and dangerous at the same time. http://hackaday.com/2015/10/16/code-craft-when-define-is-considered-harmful/

CatsLoveJazz: So in this test it seems that using a global variable is somewhat slower than creating a new local variable.

And now you and @econjack and @septillion are falling victim to an overgeneralizing based on a single contrived example. In other words, you are both optimizing too soon. Which, as Mr. Knuth has mentioned, is the root of all evil.

Which is slower when the compiler has to create a full stack frame? Are automatics (locals) slower in that case? Or do they remain faster?

Which is slower when answer is correctly scoped (it should be module instead of global)? Does the optimizer realize the scope is even narrower then eliminate the persistent storage?

[quote author=Coding Badly link=msg=2881574 date=1471200406] And now you and @econjack and @septillion are falling victim to an overgeneralizing based on a single contrived example. In other words, you are both optimizing too soon. Which, as Mr. Knuth has mentioned, is the root of all evil. [/quote] Of course, it's pretty safe to sit back and criticize something, but then not offer an alternative way to shed more light on the topic. Since we're "optimizing too soon", what code would you offer as an alternative test to answer the OP's question?

The alternative test is to take the OP's code (which we have not yet seen) and use it to test.