void setup(){
Serial.begin(115200);
}//setup()
void loop(){
foo();
delay(500);
}//loop()
void foo(){
static int bar = foobar();
Serial.print("bar:")
Serial.println(bar);
bar++;
}//foo()
int foobar(){
Serial.println("This is foobar");
return 0;
}//foobar()
In this program foobar() is called exactly once at the first run of foo(). To me that means that the compiler must insert some code to skip the line: static int bar = foobar(); on consecutive calls. It must also have some means to keep track of weather it is the fist call or not in runtime.
My question: Does anyone know of these mechanisms and how to manipulate them? That is
Check if this is the first call without declaring a static variable
Reset the flag that indicates a already called function
It's your use of static. Since you only call foobar as part of the initialisation of a static variable, it only gets called in the first call of foo().
Remove the word static and it'll be called every time.
Alternatively you could still use a static variable thus.
Because the variable is declared static, it needs to be initialized once. That happens by calling foobar(). Once the variable has a value, foobar() isn't called again.
Actually, if you put Serial.print() statements in setup(), loop(), foo(), and foobar(), you'll see that foobar() is probably not called when you think it is.
You can use boolean variables, and check them to see if it is necessary to call any function.
This was not what i was asking. I know about static variables and when they are called. My question was how the mechanisms causing this work, if they are accessible and if they could be manipulated. What i want to do is
Call foobar once at the first call without the need for a static variable or some other code but just by utilizing what the compiler does with a static variable
Be able to reset the flag so that foobar() is called again at some later time
Call foobar once at the first call without the need for a static variable or some other code but just by utilizing what the compiler does with a static variable
Those requirements look incompatible. You need to do something, so why not just have foobar() set a boolean variable indicating that that is has been called and check that before calling it again. To call it again just change the boolean variable.
I want to know how it works inside. As i said the mechanism achieving this must be there. So how does it work and how can i utilize it.
But you are probably right, this mechanism would most likely not be inserted unless there is need for it e.g there is a static variable declared
Knowing how it works as an academic exercise is one thing, but wasting time on trying to interfere with it is another. It seems to me that you would need to write some assembly language commands to do it and if you are going to do that why not just use C++ and let the compiler do the heavy lifting ?
nilton61:
I want to know how it works inside. As i said the mechanism achieving this must be there. So how does it work and how can i utilize it.
But you are probably right, this mechanism would most likely not be inserted unless there is need for it e.g there is a static variable declared
Ofcourse there is a mechanism inside, but it's an inherent part of C++, not something you can access.
What the people above are saying is the best way of handling it. You seem to have 2 requirements: making sure it is initialized, and be able to cause it to get reinitialized on demand.
For both just a flag indicating if it has been initialized is required. On startup it's false, so before using the value, initialize it and set the flag to true. If you want to force a reinitialization, just set the flag to false again, and the next call for it will initialize it again.
It's not because one of the side effects of a static variable is immediate initialization, that trying to abuse it for this goal is in any sense a good idea (or even a possible idea). How it does that is not via a macro or anything else you can access, but something deep internal you won't be able to reach, and if you knew how to reach it, you'd know why you would never try to mess with it.
If you've really got your mind set on using this static mechanism for this, i hope you're ready for countless hours of learning the C++ compiler internals :). enjoy
nilton61:
I dont think trying to interfere is a waste of time. Much knowledge has been gained that way. I got this working:
void setup(){
Serial.begin(115200);
}//setup()
void loop(){
foo();
delay(500);
}//loop()
void foo(){
static int bar = foobar();
Serial.print("bar:");
Serial.println(bar);
bar++;
if(bar == 10) _ZGVZ3foovE3bar = 0;
}//foo()
int foobar(){
Serial.println("This is foobar");
return 0;
}//foobar()
And now you have a piece of incredibly fragile and obtuse code that depends on undocumented behavior in the compiler that will, in all probability, stop working at some point in the future when some minor change is made in the compiler. And it will be absolutely incomprehensible to anyone else looking at your code. A year from now, even you won't remember why you did it. And for what benefit? What do you gain over one or two lines of simple, obvious, robust c code?
What you're trying to do is FAR better done in c code.
Of course it does. And i got it working, which does not mean that i am going to use it. But in my world ALL knowledge is beneficial. And i have encountered countless situations where knowledge gained by curiosity or just for the challenge of it turned out to be extremely useful in some situation that is completely unforeseeable.
nilton61:
Of course it does. And i got it working, which does not mean that i am going to use it. But in my world ALL knowledge is beneficial. And i have encountered countless situations where knowledge gained by curiosity or just for the challenge of it turned out to be extremely useful in some situation that is completely unforeseeable.
Glad to see you know better than to use it ^^
And your low level debugging skills are pretty good :). But unless you've got a love for reverse engineering programs, and need to know what it means when you encounter such things, i agree with the others that this exercise was pretty pointless...
Doing all that work and then finding such a solution for such a trivial issue to solve?
I just happen to have a love for challenges. And that served me well over the years. And it wasn't that hard. And the real knowledge gain wasn't in solving the original problem but to learn how to make and use objectdumps for both the code and the symbol table. And on a more general level how search for and filter that kind of information
nilton61:
I dont think trying to interfere is a waste of time. Much knowledge has been gained that way. I got this working:
void setup(){
Serial.begin(115200);
}//setup()
void loop(){
foo();
delay(500);
}//loop()
void foo(){
static int bar = foobar();
Serial.print("bar:");
Serial.println(bar);
bar++;
if(bar == 10) _ZGVZ3foovE3bar = 0;
}//foo()
int foobar(){
Serial.println("This is foobar");
return 0;
}//foobar()
Fair play to you but I don't think this is very portable. You've got to untangle the name mangling which may not be consistent. But I agree, it's not entirely a wasted exercise.
Did you try adding Serial.print() statements to the functions involved? You would have seen that foobar() was called BEFORE setup(), when the sketch first starts, and the variable needs its initial value.
Static local variables are initialized only when they are first used. In this case, the static local variable bar is initialized the first time foo() is called, so foobar() is called at that time and no earlier.