8

Behold this insanity:

enum WhatArduinoIs {
  Easy, But, Insane, Obsolete, And, Far, Worse, Than, mBed
};

void TellMe(WhatArduinoIs pls) { }

void setup() { }
void loop() { }

I'm pretty good at C++, so I'm fairly sure that should compile. However I get this error:

sketch_jan21b.ino:3:13: error: variable or field 'TellMe' declared void
sketch_jan21b.ino:3:13: error: 'WhatArduinoIs' was not declared in this scope
Error compiling.

I've encountered the Arduino "IDE"'s propensity for insane and totally unrobust modification of programs before. Specifically when you #include libraries Arduino only magically adds the relevant C++ files if the #include is in your main sketch. #include <LiquidCrystal.h> in another C++ file? Link errors.

I suspect in this case it is Arduino magically trying to add function declarations to the start of the file so their order doesn't matter. I.e. it turns the file into this:

void TellMe(WhatArduinoIs pls);

enum WhatArduinoIs {
  Easy, But, Insane, Obsolete, And, Far, Worse, Than, mBed
};

void TellMe(WhatArduinoIs pls) { }

void setup() { }
void loop() { }

That obviously doesn't work. How can I tell Arduino to leave my damn program alone?

Timmmm
  • 183
  • 2
  • 5

3 Answers3

6

You can workaround the issue by putting your enum and function into a namespace. You can even take advantage of C++ unnamed namespaces if you like:

namespace
{
  enum WhatArduinoIs {
    Easy, But, Insane, Obsolete, And, Far, Worse, Than, mBed
  };

  void TellMe(WhatArduinoIs pls) { }
}

void setup() { }
void loop() { }

It's annoying (as are many things in the Arduino IDE), but it seems to work.

If you're more experienced with programming then you might want to consider using a 3rd party IDE with an Arduino plugin, such as Eclipse. The Arduino IDE is really only designed for beginners.

Peter Bloomfield
  • 10,982
  • 9
  • 48
  • 87
4

You seem to be correct about what the arduino IDE is doing to your sketch.

Arduino will not preprocess any .h or .cpp files, so you could use a second file. you could also break the IDE's function locating regex with a dummy throw() statement like this:

void TellMe(WhatArduinoIs pls) throw() { }

The dummy throw allows it to compile for me on 1.5.8

BrettFolkins
  • 4,441
  • 1
  • 15
  • 26
1

All you need is a function prototype. I have a detailed explanation at Classes and objects: how many and which file types I actually need to use them?

So, this compiles:

enum WhatArduinoIs {
  Easy, But, Insane, Obsolete, And, Far, Worse, Than, mBed
};

void TellMe(WhatArduinoIs pls);  // prototype
void TellMe(WhatArduinoIs pls) 
  {
  }
void setup() { }
void loop() { }

Off-site reference: How to avoid the quirks of the IDE sketch file pre-preprocessing

Nick Gammon
  • 38,901
  • 13
  • 69
  • 125