jwatte:
A static function variable will only be initialized the first time the function is called.
And we can prove that, which is nice.
Given this file "foo.h":
class foo
{
public:
foo ();
};
And this sketch:
#include "foo.h"
extern "C" {
__extension__ typedef int __guard __attribute__((mode (__DI__)));
int __cxa_guard_acquire(__guard *g) { return !*(char *)(g); };
void __cxa_guard_release (__guard *g) { *(char *)g = 1; };
void __cxa_guard_abort (__guard *) { };
} // end extern "C"
foo & getFoo ()
{
static foo x;
return x;
} // end of getFoo
// constructor
foo::foo ()
{
Serial.println ("foo constructed.");
} // end of foo::foo
void setup ()
{
Serial.begin (115200);
Serial.println ("starting");
foo & myFoo = getFoo ();
Serial.println ("foo now exists");
} // end of setup
void loop () {}
This sketch uses getFoo to avoid the "static member initialization fiasco" - that is, the unpredictable order in which static members are initialized. It avoids it by forcing you to explicitly get a reference to foo, via getFoo, when you need it. However as the debugging shows, foo is not initialized at program startup, but when the first attempt to get it is made.
starting
foo constructed.
foo now exists
And you can see from the generated code that there is indeed a test generated, and depending on the test, foo's constructor at 0xC0 is called:
foo & getFoo ()
{
static foo x;
ce: 80 91 3c 01 lds r24, 0x013C
d2: 88 23 and r24, r24
d4: 39 f4 brne .+14 ; 0xe4 <_Z6getFoov+0x16>
d6: 84 e4 ldi r24, 0x44 ; 68
d8: 91 e0 ldi r25, 0x01 ; 1
da: 0e 94 60 00 call 0xc0 ; 0xc0 <_ZN3fooC1Ev>
void setup ();
void loop ();
extern "C" {
__extension__ typedef int __guard __attribute__((mode (__DI__)));
int __cxa_guard_acquire(__guard *g) { return !*(char *)(g); };
void __cxa_guard_release (__guard *g) { *(char *)g = 1; };
de: 81 e0 ldi r24, 0x01 ; 1
e0: 80 93 3c 01 sts 0x013C, r24
foo & getFoo ()
{
static foo x;
return x;
}
e4: 84 e4 ldi r24, 0x44 ; 68
e6: 91 e0 ldi r25, 0x01 ; 1
e8: 08 95 ret
Thanks jwatte for clarifying something that was just lurking in the recesses of my mind. Now I know, static variables inside a function, and global static variables, are simply not identical in functionality.
bperrybap:
I have yet to see a compiler do anything special for initialized data variables as shown
in the earlier example inside the function.
See the above example, Bill.