I am little bit confused in the follwoing program.
void myfunction(){
int my_stack=0;
static int my_static=0;
Serial.print("my_static=");
Serial.println(my_static);
Serial.print("stack=");
Serial.println(my_stack);
my_stack++;
my_static++;
}
my_static variable, declared as static within a function, retains its value between successive calls to my_function() while my_stack does not. The output of 5 successive calls to my_function() is
every time when myfunction() runs it comiles static int my_static=0; then how my_static can be increased?
No. When the code runs, nothing is compiled.
When the code is compiled, the compiler notices the static keyword in front of my_static and generates code to initialize the variable ONCE. The compiler notices the lack of the static keyword in front of stack, and generates code to initialize the variable every time.
When you define a local variable as static and equate it to something you are telling it the starting value only. This value only gets assigned once.
It is functionally the same as a global variable, except the scope (where you can access it from) is more limited.
The code to assign the value to the static variable is run during the startup phase (not the setup function - before even that runs) - a process called "crt0" for "C RunTime phase 0". This copies all the values for the pre-set (static and global) variables from flash into RAM, and that is the only time these initialization values are ever assigned.
In effect the "=0" of your static declaration is not performed there, but right at the start of the program before even setup() runs.
Your definition of my_static tells the compiler several things about the variable:
Because it is defined within myfunction(), my_static "lives" and is only visible within the opening and closing braces of myfunction(). That is, my_static has local scope within myfunction().
Because your definition of my_static is prefaced with the keyword static, it's as though the compiler removes the line of code that defines my_static out of myfunction() and places it before setup(). This means the definition is only read at program startup. This causes my_static to get a memory address (i.e., an lvalue) where it will "live" for the entire running of the program and initializes its value (i.e., its rvalue) to 0.
Therefore, when the code enters myfunction() the first time, my_static becomes visible (it's in scope). When the statement my_static++ is executed, the compiler fetches the rvalue from memory (i.e., 0) and increments it (rvalue now equals 1). Because you used the static keyword, my_static is not reallocated each time myfunction() is called. When the second call is performed, the same lvalue is used to fetch the rvalue (which is now 1) and it is again incremented (i.e., rvalue =2). This is why static variables "remember" their previous values. In short, your code is doing exactly what a static variable should do: get allocated once before the program starts and never get reallocated again. Because its lvalue is never reassigned, its rvalue is retained between function calls.
then i see some examples declared this static at the beginning of the sketch even before void setup()
It's only useful when you make a sketch with multiple files and you want global variables of the same name in more than one file. You add the static keyword to limit this variable to the current file.
Say you have in file1.ino
int bla = 1;
void setup()
{
...
}
void loop()
{
...
}
And in file2.cpp you have:
int bla = 2;
When you compile you will have an error about multiple definitions of variable "bla", because both files are merged (basically). So you change file2.cpp to:
static int bla = 2;
And there is no more error, because this variable now belong only to file2.cpp.
guix:
It's only useful when you make a sketch with multiple files and you want global variables of the same name in more than one file. You add the static keyword to limit this variable to the current file.
Say you have in file1.ino
int bla = 1;
void setup()
{
...
}
void loop()
{
...
}
And in file2.cpp you have:
int bla = 2;
When you compile you will have an error about multiple definitions of variable "bla", because both files are merged (basically). So you change file2.cpp to:
static int bla = 2;
And there is no more error, because this variable now belong only to file2.cpp.
i don't really get it,
i know from other languages that static or the world specific for that language means this variable can be used inside one function only, global means any functions can use it
i made a little search i found on a forum that they say a static variable means it can be used in 1 function only the one declared in, but can not be used in another unless it's not static
about your example i don't get it ! why is it .cpp and not .ino ?
and why would i have multiple files ?! you mean multiple tabs ?
It is functionally the same as a global variable, except the scope (where you can access it from) is more limited.
majenko:
When you define a local variable as static and equate it to something you are telling it the starting value only. This value only gets assigned once.
It is functionally the same as a global variable, except the scope (where you can access it from) is more limited.
The code to assign the value to the static variable is run during the startup phase (not the setup function - before even that runs) - a process called "crt0" for "C RunTime phase 0". This copies all the values for the pre-set (static and global) variables from flash into RAM, and that is the only time these initialization values are ever assigned.
In effect the "=0" of your static declaration is not performed there, but right at the start of the program before even setup() runs.
Good description, but comparing static to global , even as in functionality only, is IMHO iffy.
The main purpose of "static" variable is - it gets allocated and ASSIGNED once.
And it has nothing to do with Arduino IDE Setup function, as you pointed out.
And its accessibility / scope is same as any other variable - has nothing to do with "static" either.
firashelou:
i don't really get it,
i know from other languages that static or the world specific for that language means this variable can be used inside one function only, global means any functions can use it
i made a little search i found on a forum that they say a static variable means it can be used in 1 function only the one declared in, but can not be used in another unless it's not static
about your example i don't get it ! why is it .cpp and not .ino ?
and why would i have multiple files ?! you mean multiple tabs ?
and why would i have multiple files ?! you mean multiple tabs ?
Unfortunately yet another Arduino.inc coined term.
"Tab" is common name for GUI control, file contains your code.
Using multiple files is beneficial in organizing your code into logical, easier to manage units - for example one file blinks LED and another writes to LCD , yet another keeps your robot moving etc.
You can share files between applications - "code once , reuse many times " as another somewhat forgotten way to code software. Or you can call it "cut and paste" if you prefer.
Vaclav:
And its accessibility / scope is same as any other variable - has nothing to do with "static" either.
No, that is not right. It absolutely DOES limit scope to the current "block". A static variable placed into a .c or .cpp file outside any function or block will be visible ONLY within that one file, and not to any other files linked into the build. In c/c++, using static forces BOTH persistence, AND limited scope.
majenko:
In effect the "=0" of your static declaration is not performed there, but right at the start of the program before even setup() runs.
Bang! Relying on this statement will hurt one day.
What you are seeing is the result of link time optimizations. You should only expect the value to be set when the declaration is first encountered in normal code flow.
int func(){
Serial.print("Or is this?");
return 1;
}
void setup() {
Serial.begin(9600);
Serial.println("Is this printed first?");
}
void loop() {
static int i = func();
}
RayLivingston:
No, that is not right. It absolutely DOES limit scope to the current "block". A static variable placed into a .c or .cpp file outside any function or block will be visible ONLY within that one file, and not to any other files linked into the build. In c/c++, using static forces BOTH persistence, AND limited scope.
Regards,
Ray L.
Ray, you sure like to split hair - "the scope of the static (variable) IS SAME as any other variable" .
Or - the scope of static ( variable) follows SAME rules as any other variable.
No need to muddy the waters adding blocks, files , functions etc.
But , whatever floats your boat.
Vaclav:
Ray, you sure like to split hair - "the scope of the static (variable) IS SAME as any other variable" .
Or - the scope of static ( variable) follows SAME rules as any other variable.
No need to muddy the waters adding blocks, files , functions etc.
But , whatever floats your boat.
It's not splitting hairs. You clearly don't understand the full effect of static. It absolutely DOES change the scope in some cases. An "int" and a "static int" at file scope do NOT have the same scope.