Variable declaration inside main loopAre global variables evil in Arduino?Would an infinite loop inside loop() perform faster?What is the difference between declaring a variable outside of loop and declaring static inside loop?Conver char value to variable?Can I automatically loop inside a library?Issue with leOS2 for one-time tasksLoop inside switch statementHow can I update global variable within a loop from outside the loop?Is a variable declaration inside a loop static declaration or dynamic?delay() not working inside loop() blockdeclared variable inside void setup is forgotten in void loop
Can a landlord force all residents to use the landlord's in-house debit card accounts?
A sequence that changes sign finally at infinity?
Is it okay to use open source code to do an interview task?
How insert vertex in face?
How many tone holes are there actually in different orchestral woodwind instruments?
Is there a method for differentiating informative comments from commented out code?
Is it possible to complete a PhD in CS in 3 years?
Would a carnivorous diet be able to support a giant worm?
How do I explain that I don't want to maintain old projects?
Is there a strong legal guarantee that the U.S. can give to another country that it won't attack them?
What does collachrimation mean?
How was the Shuttle loaded and unloaded from its carrier aircraft?
When did "&" stop being taught alongside the alphabet?
Distance between horizontal tree levels
Why does Trump want a citizenship question on the census?
IX-NAY on the IX-SAY
What was this character's plan?
Why does the Antonov AN-225 not have any winglets?
Is it stylistically sound to use onomatopoeic words?
Can Jimmy hang on his rope?
Is it better in terms of durability to remove card+battery or to connect to charger/computer via USB-C?
What does Middle English "bihiȝten" mean?
Would a Nikon FG 20 film SLR camera take pictures without batteries?
What's it called when the bad guy gets eaten?
Variable declaration inside main loop
Are global variables evil in Arduino?Would an infinite loop inside loop() perform faster?What is the difference between declaring a variable outside of loop and declaring static inside loop?Conver char value to variable?Can I automatically loop inside a library?Issue with leOS2 for one-time tasksLoop inside switch statementHow can I update global variable within a loop from outside the loop?Is a variable declaration inside a loop static declaration or dynamic?delay() not working inside loop() blockdeclared variable inside void setup is forgotten in void loop
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
In the past I declared variables inside the main loop which worked just fine.
In a new project I did the same:
void loop(void)
uint8_t counter;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
But then the output of the variable counter shows that for some reason the counter variable is reset to 0 instead of counting up. This happens even after the button is released.
The scope of the variable counter is the main loop and I just assumed that it will keep its value and count up.
What might be the reason for this variable to reset to 0?
Is it that other functions are called within the main loop?
Is it that an interrupt handler is called every now and then?
The solution I've found is to declare the variable as static:
static uint8_t counter;
Then it increments as expected.
Even though I've found a solution I'd really like to understand what the problem with my first approach was.
programming c code-review
|
show 5 more comments
In the past I declared variables inside the main loop which worked just fine.
In a new project I did the same:
void loop(void)
uint8_t counter;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
But then the output of the variable counter shows that for some reason the counter variable is reset to 0 instead of counting up. This happens even after the button is released.
The scope of the variable counter is the main loop and I just assumed that it will keep its value and count up.
What might be the reason for this variable to reset to 0?
Is it that other functions are called within the main loop?
Is it that an interrupt handler is called every now and then?
The solution I've found is to declare the variable as static:
static uint8_t counter;
Then it increments as expected.
Even though I've found a solution I'd really like to understand what the problem with my first approach was.
programming c code-review
1
This question fits better in stack overflow, since it is not related to Arduino.
– Michel Keijzers
Jun 30 at 10:20
So the main loop in the Arduino just behaves as any regular function that is called? For some reason I thought that variables declared in main() are automatically static and keep their value.
– Sören
Jun 30 at 10:27
1
No they are not, afaik the loop() is just a function that has a while(true) or while(1) inside.
– Michel Keijzers
Jun 30 at 10:29
Thank you very much for the explanation and possible solutions.
– Sören
Jun 30 at 10:35
1
@MichelKeijzers: Here ismain()
.
– Edgar Bonet
Jun 30 at 12:41
|
show 5 more comments
In the past I declared variables inside the main loop which worked just fine.
In a new project I did the same:
void loop(void)
uint8_t counter;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
But then the output of the variable counter shows that for some reason the counter variable is reset to 0 instead of counting up. This happens even after the button is released.
The scope of the variable counter is the main loop and I just assumed that it will keep its value and count up.
What might be the reason for this variable to reset to 0?
Is it that other functions are called within the main loop?
Is it that an interrupt handler is called every now and then?
The solution I've found is to declare the variable as static:
static uint8_t counter;
Then it increments as expected.
Even though I've found a solution I'd really like to understand what the problem with my first approach was.
programming c code-review
In the past I declared variables inside the main loop which worked just fine.
In a new project I did the same:
void loop(void)
uint8_t counter;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
But then the output of the variable counter shows that for some reason the counter variable is reset to 0 instead of counting up. This happens even after the button is released.
The scope of the variable counter is the main loop and I just assumed that it will keep its value and count up.
What might be the reason for this variable to reset to 0?
Is it that other functions are called within the main loop?
Is it that an interrupt handler is called every now and then?
The solution I've found is to declare the variable as static:
static uint8_t counter;
Then it increments as expected.
Even though I've found a solution I'd really like to understand what the problem with my first approach was.
programming c code-review
programming c code-review
edited Jun 30 at 10:29
Michel Keijzers
7,5556 gold badges20 silver badges41 bronze badges
7,5556 gold badges20 silver badges41 bronze badges
asked Jun 30 at 10:17
SörenSören
112 bronze badges
112 bronze badges
1
This question fits better in stack overflow, since it is not related to Arduino.
– Michel Keijzers
Jun 30 at 10:20
So the main loop in the Arduino just behaves as any regular function that is called? For some reason I thought that variables declared in main() are automatically static and keep their value.
– Sören
Jun 30 at 10:27
1
No they are not, afaik the loop() is just a function that has a while(true) or while(1) inside.
– Michel Keijzers
Jun 30 at 10:29
Thank you very much for the explanation and possible solutions.
– Sören
Jun 30 at 10:35
1
@MichelKeijzers: Here ismain()
.
– Edgar Bonet
Jun 30 at 12:41
|
show 5 more comments
1
This question fits better in stack overflow, since it is not related to Arduino.
– Michel Keijzers
Jun 30 at 10:20
So the main loop in the Arduino just behaves as any regular function that is called? For some reason I thought that variables declared in main() are automatically static and keep their value.
– Sören
Jun 30 at 10:27
1
No they are not, afaik the loop() is just a function that has a while(true) or while(1) inside.
– Michel Keijzers
Jun 30 at 10:29
Thank you very much for the explanation and possible solutions.
– Sören
Jun 30 at 10:35
1
@MichelKeijzers: Here ismain()
.
– Edgar Bonet
Jun 30 at 12:41
1
1
This question fits better in stack overflow, since it is not related to Arduino.
– Michel Keijzers
Jun 30 at 10:20
This question fits better in stack overflow, since it is not related to Arduino.
– Michel Keijzers
Jun 30 at 10:20
So the main loop in the Arduino just behaves as any regular function that is called? For some reason I thought that variables declared in main() are automatically static and keep their value.
– Sören
Jun 30 at 10:27
So the main loop in the Arduino just behaves as any regular function that is called? For some reason I thought that variables declared in main() are automatically static and keep their value.
– Sören
Jun 30 at 10:27
1
1
No they are not, afaik the loop() is just a function that has a while(true) or while(1) inside.
– Michel Keijzers
Jun 30 at 10:29
No they are not, afaik the loop() is just a function that has a while(true) or while(1) inside.
– Michel Keijzers
Jun 30 at 10:29
Thank you very much for the explanation and possible solutions.
– Sören
Jun 30 at 10:35
Thank you very much for the explanation and possible solutions.
– Sören
Jun 30 at 10:35
1
1
@MichelKeijzers: Here is
main()
.– Edgar Bonet
Jun 30 at 12:41
@MichelKeijzers: Here is
main()
.– Edgar Bonet
Jun 30 at 12:41
|
show 5 more comments
3 Answers
3
active
oldest
votes
Michael's answer was good, as usual. Let me give you some more background though:
In C/C++ (And in most modern languages) variables have a "scope", or an area where they are defined.
Global scope:
Variables declared at the top level of your program have global scope, and exist for the life of your program. These variables are usually created on the .data or .bss sections.
Local scope
Variables declared inside a function have local scope. Unless they are static
, they get created when the function is entered, and get discarded when the function exits. These variables are created on the stack as part of the function's stack frame.
Object scope
In C++ and other object-oriented languages, instances of objects have their own scope, "instance variables". Every instance of an object has its own set of instance variables. (Think of cars, and a car radio. You and I might own the exact same model of car, but if I set my car's radio station and you set your car's radio to a different station, each instance of the car has a different setting for the radio station.)
Static variables:
Static variables are variables that are declared "statically." That means that they are only created once and persist, even if they are declared inside a scope like a function or a class instance. These have the lifespan of a global variable but can be declared inside a function or in an object.
Loop is a function, so variables declared inside of loop()
are local variables. They get created anew every time the function is called, and discarded every time the function exits.
1
+1 for the great explanation and background
– Michel Keijzers
Jun 30 at 12:31
add a comment |
Your code has a couple of bugs. First you don't initialize counter before using it. Second the variable 'counter' has limited scope, it has no definition when loop() exits. If you want this variable to stay around declare it as static.
Both bugs corrected
e.g.:
void loop(void)
static uint8_t counter = 0;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
Note: Initializing counter to 0 only happens once, on subsequent calls to loop() counter will retain it's previous value.
add a comment |
The problem is that you declare a new variable. So even though the name is the same, the local variable is destroyed at the end of the loop and recreated at the beginning.
Actually, there is no good solution:
- Global variables are best to be avoided. They can be seen as 'singleton's', e.g. variables that are needed at many places in the code and have only one occurrence.
- As you found out, static solves the problem. I would use this option, although personally I'm not a fan of static variables.
Another way is to put the loop in a while, so you get:
void loop(void)
uint8_t counter = 0; // Always initialize variables
while (true)
// Your code
This will work too, as your counter is only initialized once, however the loop is already (internally) a while loop, so you have two.
A much better way but more extra work, is to create a C++ class, where counter can be a class variable, which is local for that class (which could still be a singleton). Of course this is only true when the counter variable is belonging logically to that class, if it is not, just keep it a global variable (updated after Edgar Bonet's remark).
Making the counter a property of an object which is itself a global variable would be no better than making the counter itself global. It would actually be worse: any complexity that serves no useful purpose is always a bad thing in a program.
– Edgar Bonet
Jun 30 at 11:18
@EdgarBonet You are right when that variable (the counter) is unrelated to the class that would be created (I was assuming so, but I will update my answer). If the counter is unrelated, than you are absolutely right.
– Michel Keijzers
Jun 30 at 12:33
Could you explain why simply using a global variable should be avoided? I see no disadvantage in terms of memory usage or performance. I'd say, using a global variable is just fine in many situations. In my opinion making it more complicate is also not very elegant.
– Sim Son
Jun 30 at 12:39
@SimSon There is no disadvantage in terms of memory usage or performance, bit if you make all variables global and you have thousands of them, you can imagine what mess it will be. This will not happen easily in an Arduino Uno with 2 KB memory, but it's best to keep functionality isolated. Actually, one of the worst things about the Arduino IDE is that it works best with just an Ino file, and most people do not get further creating classes or separate files.
– Michel Keijzers
Jun 30 at 12:41
@SimSon: See Are global variables evil in Arduino?.
– Edgar Bonet
Jun 30 at 12:42
|
show 9 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("schematics", function ()
StackExchange.schematics.init();
);
, "cicuitlab");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "540"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f66713%2fvariable-declaration-inside-main-loop%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Michael's answer was good, as usual. Let me give you some more background though:
In C/C++ (And in most modern languages) variables have a "scope", or an area where they are defined.
Global scope:
Variables declared at the top level of your program have global scope, and exist for the life of your program. These variables are usually created on the .data or .bss sections.
Local scope
Variables declared inside a function have local scope. Unless they are static
, they get created when the function is entered, and get discarded when the function exits. These variables are created on the stack as part of the function's stack frame.
Object scope
In C++ and other object-oriented languages, instances of objects have their own scope, "instance variables". Every instance of an object has its own set of instance variables. (Think of cars, and a car radio. You and I might own the exact same model of car, but if I set my car's radio station and you set your car's radio to a different station, each instance of the car has a different setting for the radio station.)
Static variables:
Static variables are variables that are declared "statically." That means that they are only created once and persist, even if they are declared inside a scope like a function or a class instance. These have the lifespan of a global variable but can be declared inside a function or in an object.
Loop is a function, so variables declared inside of loop()
are local variables. They get created anew every time the function is called, and discarded every time the function exits.
1
+1 for the great explanation and background
– Michel Keijzers
Jun 30 at 12:31
add a comment |
Michael's answer was good, as usual. Let me give you some more background though:
In C/C++ (And in most modern languages) variables have a "scope", or an area where they are defined.
Global scope:
Variables declared at the top level of your program have global scope, and exist for the life of your program. These variables are usually created on the .data or .bss sections.
Local scope
Variables declared inside a function have local scope. Unless they are static
, they get created when the function is entered, and get discarded when the function exits. These variables are created on the stack as part of the function's stack frame.
Object scope
In C++ and other object-oriented languages, instances of objects have their own scope, "instance variables". Every instance of an object has its own set of instance variables. (Think of cars, and a car radio. You and I might own the exact same model of car, but if I set my car's radio station and you set your car's radio to a different station, each instance of the car has a different setting for the radio station.)
Static variables:
Static variables are variables that are declared "statically." That means that they are only created once and persist, even if they are declared inside a scope like a function or a class instance. These have the lifespan of a global variable but can be declared inside a function or in an object.
Loop is a function, so variables declared inside of loop()
are local variables. They get created anew every time the function is called, and discarded every time the function exits.
1
+1 for the great explanation and background
– Michel Keijzers
Jun 30 at 12:31
add a comment |
Michael's answer was good, as usual. Let me give you some more background though:
In C/C++ (And in most modern languages) variables have a "scope", or an area where they are defined.
Global scope:
Variables declared at the top level of your program have global scope, and exist for the life of your program. These variables are usually created on the .data or .bss sections.
Local scope
Variables declared inside a function have local scope. Unless they are static
, they get created when the function is entered, and get discarded when the function exits. These variables are created on the stack as part of the function's stack frame.
Object scope
In C++ and other object-oriented languages, instances of objects have their own scope, "instance variables". Every instance of an object has its own set of instance variables. (Think of cars, and a car radio. You and I might own the exact same model of car, but if I set my car's radio station and you set your car's radio to a different station, each instance of the car has a different setting for the radio station.)
Static variables:
Static variables are variables that are declared "statically." That means that they are only created once and persist, even if they are declared inside a scope like a function or a class instance. These have the lifespan of a global variable but can be declared inside a function or in an object.
Loop is a function, so variables declared inside of loop()
are local variables. They get created anew every time the function is called, and discarded every time the function exits.
Michael's answer was good, as usual. Let me give you some more background though:
In C/C++ (And in most modern languages) variables have a "scope", or an area where they are defined.
Global scope:
Variables declared at the top level of your program have global scope, and exist for the life of your program. These variables are usually created on the .data or .bss sections.
Local scope
Variables declared inside a function have local scope. Unless they are static
, they get created when the function is entered, and get discarded when the function exits. These variables are created on the stack as part of the function's stack frame.
Object scope
In C++ and other object-oriented languages, instances of objects have their own scope, "instance variables". Every instance of an object has its own set of instance variables. (Think of cars, and a car radio. You and I might own the exact same model of car, but if I set my car's radio station and you set your car's radio to a different station, each instance of the car has a different setting for the radio station.)
Static variables:
Static variables are variables that are declared "statically." That means that they are only created once and persist, even if they are declared inside a scope like a function or a class instance. These have the lifespan of a global variable but can be declared inside a function or in an object.
Loop is a function, so variables declared inside of loop()
are local variables. They get created anew every time the function is called, and discarded every time the function exits.
edited Jun 30 at 15:29
answered Jun 30 at 10:35
Duncan CDuncan C
2,5922 gold badges8 silver badges20 bronze badges
2,5922 gold badges8 silver badges20 bronze badges
1
+1 for the great explanation and background
– Michel Keijzers
Jun 30 at 12:31
add a comment |
1
+1 for the great explanation and background
– Michel Keijzers
Jun 30 at 12:31
1
1
+1 for the great explanation and background
– Michel Keijzers
Jun 30 at 12:31
+1 for the great explanation and background
– Michel Keijzers
Jun 30 at 12:31
add a comment |
Your code has a couple of bugs. First you don't initialize counter before using it. Second the variable 'counter' has limited scope, it has no definition when loop() exits. If you want this variable to stay around declare it as static.
Both bugs corrected
e.g.:
void loop(void)
static uint8_t counter = 0;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
Note: Initializing counter to 0 only happens once, on subsequent calls to loop() counter will retain it's previous value.
add a comment |
Your code has a couple of bugs. First you don't initialize counter before using it. Second the variable 'counter' has limited scope, it has no definition when loop() exits. If you want this variable to stay around declare it as static.
Both bugs corrected
e.g.:
void loop(void)
static uint8_t counter = 0;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
Note: Initializing counter to 0 only happens once, on subsequent calls to loop() counter will retain it's previous value.
add a comment |
Your code has a couple of bugs. First you don't initialize counter before using it. Second the variable 'counter' has limited scope, it has no definition when loop() exits. If you want this variable to stay around declare it as static.
Both bugs corrected
e.g.:
void loop(void)
static uint8_t counter = 0;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
Note: Initializing counter to 0 only happens once, on subsequent calls to loop() counter will retain it's previous value.
Your code has a couple of bugs. First you don't initialize counter before using it. Second the variable 'counter' has limited scope, it has no definition when loop() exits. If you want this variable to stay around declare it as static.
Both bugs corrected
e.g.:
void loop(void)
static uint8_t counter = 0;
....
if (buttonPress)
counter = 0;
...
if (someCondition == true)
Serial.println(counter);
counter++
Note: Initializing counter to 0 only happens once, on subsequent calls to loop() counter will retain it's previous value.
answered Jun 30 at 18:28
Jeff WahausJeff Wahaus
4985 bronze badges
4985 bronze badges
add a comment |
add a comment |
The problem is that you declare a new variable. So even though the name is the same, the local variable is destroyed at the end of the loop and recreated at the beginning.
Actually, there is no good solution:
- Global variables are best to be avoided. They can be seen as 'singleton's', e.g. variables that are needed at many places in the code and have only one occurrence.
- As you found out, static solves the problem. I would use this option, although personally I'm not a fan of static variables.
Another way is to put the loop in a while, so you get:
void loop(void)
uint8_t counter = 0; // Always initialize variables
while (true)
// Your code
This will work too, as your counter is only initialized once, however the loop is already (internally) a while loop, so you have two.
A much better way but more extra work, is to create a C++ class, where counter can be a class variable, which is local for that class (which could still be a singleton). Of course this is only true when the counter variable is belonging logically to that class, if it is not, just keep it a global variable (updated after Edgar Bonet's remark).
Making the counter a property of an object which is itself a global variable would be no better than making the counter itself global. It would actually be worse: any complexity that serves no useful purpose is always a bad thing in a program.
– Edgar Bonet
Jun 30 at 11:18
@EdgarBonet You are right when that variable (the counter) is unrelated to the class that would be created (I was assuming so, but I will update my answer). If the counter is unrelated, than you are absolutely right.
– Michel Keijzers
Jun 30 at 12:33
Could you explain why simply using a global variable should be avoided? I see no disadvantage in terms of memory usage or performance. I'd say, using a global variable is just fine in many situations. In my opinion making it more complicate is also not very elegant.
– Sim Son
Jun 30 at 12:39
@SimSon There is no disadvantage in terms of memory usage or performance, bit if you make all variables global and you have thousands of them, you can imagine what mess it will be. This will not happen easily in an Arduino Uno with 2 KB memory, but it's best to keep functionality isolated. Actually, one of the worst things about the Arduino IDE is that it works best with just an Ino file, and most people do not get further creating classes or separate files.
– Michel Keijzers
Jun 30 at 12:41
@SimSon: See Are global variables evil in Arduino?.
– Edgar Bonet
Jun 30 at 12:42
|
show 9 more comments
The problem is that you declare a new variable. So even though the name is the same, the local variable is destroyed at the end of the loop and recreated at the beginning.
Actually, there is no good solution:
- Global variables are best to be avoided. They can be seen as 'singleton's', e.g. variables that are needed at many places in the code and have only one occurrence.
- As you found out, static solves the problem. I would use this option, although personally I'm not a fan of static variables.
Another way is to put the loop in a while, so you get:
void loop(void)
uint8_t counter = 0; // Always initialize variables
while (true)
// Your code
This will work too, as your counter is only initialized once, however the loop is already (internally) a while loop, so you have two.
A much better way but more extra work, is to create a C++ class, where counter can be a class variable, which is local for that class (which could still be a singleton). Of course this is only true when the counter variable is belonging logically to that class, if it is not, just keep it a global variable (updated after Edgar Bonet's remark).
Making the counter a property of an object which is itself a global variable would be no better than making the counter itself global. It would actually be worse: any complexity that serves no useful purpose is always a bad thing in a program.
– Edgar Bonet
Jun 30 at 11:18
@EdgarBonet You are right when that variable (the counter) is unrelated to the class that would be created (I was assuming so, but I will update my answer). If the counter is unrelated, than you are absolutely right.
– Michel Keijzers
Jun 30 at 12:33
Could you explain why simply using a global variable should be avoided? I see no disadvantage in terms of memory usage or performance. I'd say, using a global variable is just fine in many situations. In my opinion making it more complicate is also not very elegant.
– Sim Son
Jun 30 at 12:39
@SimSon There is no disadvantage in terms of memory usage or performance, bit if you make all variables global and you have thousands of them, you can imagine what mess it will be. This will not happen easily in an Arduino Uno with 2 KB memory, but it's best to keep functionality isolated. Actually, one of the worst things about the Arduino IDE is that it works best with just an Ino file, and most people do not get further creating classes or separate files.
– Michel Keijzers
Jun 30 at 12:41
@SimSon: See Are global variables evil in Arduino?.
– Edgar Bonet
Jun 30 at 12:42
|
show 9 more comments
The problem is that you declare a new variable. So even though the name is the same, the local variable is destroyed at the end of the loop and recreated at the beginning.
Actually, there is no good solution:
- Global variables are best to be avoided. They can be seen as 'singleton's', e.g. variables that are needed at many places in the code and have only one occurrence.
- As you found out, static solves the problem. I would use this option, although personally I'm not a fan of static variables.
Another way is to put the loop in a while, so you get:
void loop(void)
uint8_t counter = 0; // Always initialize variables
while (true)
// Your code
This will work too, as your counter is only initialized once, however the loop is already (internally) a while loop, so you have two.
A much better way but more extra work, is to create a C++ class, where counter can be a class variable, which is local for that class (which could still be a singleton). Of course this is only true when the counter variable is belonging logically to that class, if it is not, just keep it a global variable (updated after Edgar Bonet's remark).
The problem is that you declare a new variable. So even though the name is the same, the local variable is destroyed at the end of the loop and recreated at the beginning.
Actually, there is no good solution:
- Global variables are best to be avoided. They can be seen as 'singleton's', e.g. variables that are needed at many places in the code and have only one occurrence.
- As you found out, static solves the problem. I would use this option, although personally I'm not a fan of static variables.
Another way is to put the loop in a while, so you get:
void loop(void)
uint8_t counter = 0; // Always initialize variables
while (true)
// Your code
This will work too, as your counter is only initialized once, however the loop is already (internally) a while loop, so you have two.
A much better way but more extra work, is to create a C++ class, where counter can be a class variable, which is local for that class (which could still be a singleton). Of course this is only true when the counter variable is belonging logically to that class, if it is not, just keep it a global variable (updated after Edgar Bonet's remark).
edited Jun 30 at 12:34
answered Jun 30 at 10:19
Michel KeijzersMichel Keijzers
7,5556 gold badges20 silver badges41 bronze badges
7,5556 gold badges20 silver badges41 bronze badges
Making the counter a property of an object which is itself a global variable would be no better than making the counter itself global. It would actually be worse: any complexity that serves no useful purpose is always a bad thing in a program.
– Edgar Bonet
Jun 30 at 11:18
@EdgarBonet You are right when that variable (the counter) is unrelated to the class that would be created (I was assuming so, but I will update my answer). If the counter is unrelated, than you are absolutely right.
– Michel Keijzers
Jun 30 at 12:33
Could you explain why simply using a global variable should be avoided? I see no disadvantage in terms of memory usage or performance. I'd say, using a global variable is just fine in many situations. In my opinion making it more complicate is also not very elegant.
– Sim Son
Jun 30 at 12:39
@SimSon There is no disadvantage in terms of memory usage or performance, bit if you make all variables global and you have thousands of them, you can imagine what mess it will be. This will not happen easily in an Arduino Uno with 2 KB memory, but it's best to keep functionality isolated. Actually, one of the worst things about the Arduino IDE is that it works best with just an Ino file, and most people do not get further creating classes or separate files.
– Michel Keijzers
Jun 30 at 12:41
@SimSon: See Are global variables evil in Arduino?.
– Edgar Bonet
Jun 30 at 12:42
|
show 9 more comments
Making the counter a property of an object which is itself a global variable would be no better than making the counter itself global. It would actually be worse: any complexity that serves no useful purpose is always a bad thing in a program.
– Edgar Bonet
Jun 30 at 11:18
@EdgarBonet You are right when that variable (the counter) is unrelated to the class that would be created (I was assuming so, but I will update my answer). If the counter is unrelated, than you are absolutely right.
– Michel Keijzers
Jun 30 at 12:33
Could you explain why simply using a global variable should be avoided? I see no disadvantage in terms of memory usage or performance. I'd say, using a global variable is just fine in many situations. In my opinion making it more complicate is also not very elegant.
– Sim Son
Jun 30 at 12:39
@SimSon There is no disadvantage in terms of memory usage or performance, bit if you make all variables global and you have thousands of them, you can imagine what mess it will be. This will not happen easily in an Arduino Uno with 2 KB memory, but it's best to keep functionality isolated. Actually, one of the worst things about the Arduino IDE is that it works best with just an Ino file, and most people do not get further creating classes or separate files.
– Michel Keijzers
Jun 30 at 12:41
@SimSon: See Are global variables evil in Arduino?.
– Edgar Bonet
Jun 30 at 12:42
Making the counter a property of an object which is itself a global variable would be no better than making the counter itself global. It would actually be worse: any complexity that serves no useful purpose is always a bad thing in a program.
– Edgar Bonet
Jun 30 at 11:18
Making the counter a property of an object which is itself a global variable would be no better than making the counter itself global. It would actually be worse: any complexity that serves no useful purpose is always a bad thing in a program.
– Edgar Bonet
Jun 30 at 11:18
@EdgarBonet You are right when that variable (the counter) is unrelated to the class that would be created (I was assuming so, but I will update my answer). If the counter is unrelated, than you are absolutely right.
– Michel Keijzers
Jun 30 at 12:33
@EdgarBonet You are right when that variable (the counter) is unrelated to the class that would be created (I was assuming so, but I will update my answer). If the counter is unrelated, than you are absolutely right.
– Michel Keijzers
Jun 30 at 12:33
Could you explain why simply using a global variable should be avoided? I see no disadvantage in terms of memory usage or performance. I'd say, using a global variable is just fine in many situations. In my opinion making it more complicate is also not very elegant.
– Sim Son
Jun 30 at 12:39
Could you explain why simply using a global variable should be avoided? I see no disadvantage in terms of memory usage or performance. I'd say, using a global variable is just fine in many situations. In my opinion making it more complicate is also not very elegant.
– Sim Son
Jun 30 at 12:39
@SimSon There is no disadvantage in terms of memory usage or performance, bit if you make all variables global and you have thousands of them, you can imagine what mess it will be. This will not happen easily in an Arduino Uno with 2 KB memory, but it's best to keep functionality isolated. Actually, one of the worst things about the Arduino IDE is that it works best with just an Ino file, and most people do not get further creating classes or separate files.
– Michel Keijzers
Jun 30 at 12:41
@SimSon There is no disadvantage in terms of memory usage or performance, bit if you make all variables global and you have thousands of them, you can imagine what mess it will be. This will not happen easily in an Arduino Uno with 2 KB memory, but it's best to keep functionality isolated. Actually, one of the worst things about the Arduino IDE is that it works best with just an Ino file, and most people do not get further creating classes or separate files.
– Michel Keijzers
Jun 30 at 12:41
@SimSon: See Are global variables evil in Arduino?.
– Edgar Bonet
Jun 30 at 12:42
@SimSon: See Are global variables evil in Arduino?.
– Edgar Bonet
Jun 30 at 12:42
|
show 9 more comments
Thanks for contributing an answer to Arduino Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f66713%2fvariable-declaration-inside-main-loop%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
This question fits better in stack overflow, since it is not related to Arduino.
– Michel Keijzers
Jun 30 at 10:20
So the main loop in the Arduino just behaves as any regular function that is called? For some reason I thought that variables declared in main() are automatically static and keep their value.
– Sören
Jun 30 at 10:27
1
No they are not, afaik the loop() is just a function that has a while(true) or while(1) inside.
– Michel Keijzers
Jun 30 at 10:29
Thank you very much for the explanation and possible solutions.
– Sören
Jun 30 at 10:35
1
@MichelKeijzers: Here is
main()
.– Edgar Bonet
Jun 30 at 12:41