Why are there so many global variables in the examples?

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.