Beginner question: Why double before void setup?

Code below is a beginners exercise to display numbers changing on the screen.
Double is used after #include, and before void setup().
Why doesn’t it work, when I place it within void setup?

#include <Arduboy2.h>
Arduboy2 arduboy;
  double a;
  double b;
 
void setup() {
  arduboy.begin();
  arduboy.setFrameRate(30);
  a = 3;
  b = 1000;
}  
void loop() {
  arduboy.clear();
  a = (a + 1);
  b = (2000 - a);
  arduboy.print(a * b);
  arduboy.display();
}

In a nutshell, if you place the variable declarations for a and b in setup then they will be local variables only accessible inside setup. The problem is you want to modify the same variables in loop as well so you must declare them as global (at the top outside of any functions or loops).

3 Likes

Exactly as @sjm4306 says. We call it scope.

1 Like

Here’s another scopre reference:
https://en.cppreference.com/w/cpp/language/scope

There’s two important things to be aware of with scope:

  • A variable ceases to exist once the scope it was declared in has ended
  • Scope is hierarcichal - inner scopes can see all variables from outer scopes as long as those variables were declared before the inner scope began

Hopefully this code will help to illustrate some of the quirks of scoping.

// Scope level 0 - global scope

int z = 7;

void loop(void)
{
	// Scope level 1 - function scope
	int a = 0;
	arduboy.println(a);
	
	if(a == 0)
	{
		// Scope level 2 - first nested scope
		int b = 0;
		arduboy.println(b);

		// Note - no if or while or for, just curly braces
		// This is allowed for manually forcing a separate scope
		{
			// Scope level 3 - second nested scope
			int a = 4;
			arduboy.println(a);
			
			// Can see 'b'
			arduboy.println(b);
						
			// Can't see 'c' - not yet declared
			//arduboy.println(c);
			
			// 'z' is visible
			arduboy.println(z);
		}
		// The second 'a' no longer exists
		
		int c = 8;
		
		// This is a different block to the earlier scope
		// but at the same level
		{
			// Scope level 3 - second nested scope
			int a = 5;
			arduboy.println(a);
			
			// Can see 'b'
			arduboy.println(b);
						
			// Can see 'c'
			arduboy.println(c);
			
			// 'z' is visible
			arduboy.println(z);
		}
		// The third 'a' no longer exists
	}
	// 'b' no longer exists
			
	// 'z' is visible
	arduboy.println(z);
}
// The first 'a' no longer exists

void someOtherFunction(void)
{
	// Scope level 1 - function scope
	// None of the variables from loop exist here
	// but 'z' does
	arduboy.println(z);
}
1 Like

what would be better form, global declaration in the ino file or this:

void loop() {

  static Object obj = Object();

  //stuff
  }

Avoid static locals.

Global variables are initialised when the program starts, which is desirable behaviour.
static local variables are initialised when the function first runs, which is less desirable.

(I would hope that the compiler still includes both in its ‘pecentage used’ calculation because both have static storage duration.)