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.

  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() {

void loop() {

void foo() {
  // local variables:
  int myPin = 12;

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)