To #define or not to #define


1. #define vs. const

Sad but true: you find a lot of nonsense on the matter #define vs. const.

Of course, this code won't compile. It is just the original "blink.ino" with 5 different ways to set the value for led.
Check the code sizes given next to the declarations.

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:

//                       code size

      int  led = 13;  // 1084
      byte led = 13;  // 1084
const int  led = 13;  // 1076
const byte led = 13;  // 1076
#define    led   13   // 1076

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

If you add the static attribute you always get a code size of 1076 no matter of const, int, byte.

So, from a lazy point of view the int version is the shortest to key in.
If flash memory usage is important the #define version is the better one.

From a more general point of view it looks a bit different. When using the #define directive you do not declare a type.

Also the purpose of #define is it can be used for later decisions as #ifdef in conditional compiling which can be very useful.
So, by using #define for declaring a constant you are mixing two concepts.
Whatever is #define-d will be processed by the preprocessor, the constants will be evaluated by the compiler.

A good example when and how to use conditional compilation is given in the footnote on ATmega2560.

2. Drawback of #define

Have a look at this short code snippet:

// global defines:
#define myPin 13

void setup() {
  pinMode(myPin,OUTPUT);
}

void loop() {
  foo();
}

void foo() {
  // local variables:
  int myPin = 12;
  pinMode(myPin,INPUT);
}

You have a global myPin and somewhere else a local myPin which should work just fine. If you declared

const byte myPin = 13;
instead of #define there was no problem. But as the preprocessor replaces each occurrence of myPin you will get an expected unqualified-id before numeric constant error.


contact: nji(at)gmx.de