Fighting Arduino's IDE smartness

On some simple code I wrote, the IDE is reporting compiler errors which are pure nonsense. I suspect of some issue related to

http://arduino.cc/en/Guide/Troubleshooting#toc22

The troubleshooting tip describes the problem, but there is no mention on how to solve it, apart from a special case.

How can I stop Arduino from messing around with the code I wrote?

How can I see the code that is actually sent to the compiler? And the unmassaged compiler output?

Post your code and error message.

Mark

I thought this is a well-known problem. Anyways here it goes a trivial test case (tested with IDE 1.0.1, 1.0.2 gave the same problem with a similar albeit more complex case):

struct Boton {
  int pin;
};

void Chequea(Boton &b) {
}

void setup() {
}

void loop() {
}

which gives:

arco.cpp:2:14: error: variable or field ‘Chequea’ declared void
arco.cpp:2:14: error: ‘Boton’ was not declared in this scope
arco.cpp:2:21: error: ‘b’ was not declared in this scope

For the time being, I solved this specific instance by making Chequea a method of Boton, but I'm pretty sure that the problem will appear again and again.

trurl:
How can I stop Arduino from messing around with the code I wrote?

I'm afraid that when you use the Arduino IDE to build your sketch, the messing about is done for you. It's supposed to be helpful, although I must admit I'd be happy without that 'help'.

Your code declares a struct Boton but not a type Boton. If you want to define a type, you could use a typedef.

typedef struct Boton {
  int pin;
} Boton;

(Alternatively you could use 'struct Boton' instead of 'Boton', but I think defining a type is cleaner.)

Also, the IDE will be adding a function declaration for you, even though your sketch would have compiled without it. However, the declaration is placed above your code and above your own declaration and the typedefs that it depends on. You should be able to prevent the IDE from generating the declaration by putting in a declaration of your own somewhere after the declaration of the Boton type:

void Chequea(Boton &b);

The last semicolon here is not the probleM?

struct Boton {
  int pin;
}; <<< this one?

CrossRoads, PeterH,

I see quite a few C programmers here :slight_smile:

In C++, you don't need the typedef for declaring a type while declaring a struct, nor do you need the struct Boton {...} boton1`' or struct Boton boton1' syntax for declaring instances. Struct basically works the same way as for class', although with differences like default accessibility level of members and inherited classes/structs.

But I digress. Neither using the typedef trick nor adding a function declaration for `Chequea' just after the type declaration solves the problem.

struct Boton {
  int pin;
};

void Chequea(struct Boton &b) {
}

void setup() {
}

void loop() {
}

compiles with no problems.

PaulS,

That's great to know, thanks!

AFAIK the IDE uses avr-g++ 4.7.0 on Linux and 4.3.? on Windows. Both are recent enough to not require the C-ism shown in your code, so I guess that some switch is passed to the compiler that puts it on a special mode. My guess is that such mode is required for compatibility with legacy code that the Arduino or AVR system still uses.

Is there a way to see the complete command that is used to invoke the compiler?

(And is there an option somewhere to change the compiler switches? I'll like to take advantage of some C++11 features.)

Is there a way to see the complete command that is used to invoke the compiler?

Look at the File + Preferences dialog.

And is there an option somewhere to change the compiler switches?

Not using the IDE.

Look at the File + Preferences dialog.

Ok, marking the "Show verbose output during compilation" checkbox makes the trick.

The compiler is fine, there is no fancy switch passed to it. The problem is the Arduino IDE prepending the user's source code with the auto generated declarations. This is what observed:

  • Writing a declaration makes no difference: the IDE generates a declaration anyways.
  • Since the declaration generated by the IDE is placed at the top of the source file that is actually passed to the compiler, any user-defined type is undefined at the point the declaration is parsed.
  • The idiom void foo(struct S&)' is accepted because it contains a declaration of S' as an struct.'

Not using the IDE.

Ok. I looked at the preferences.txt file and even experimented with a few suspects, but there is nothing there that achieves what I want. So I guess that the only way of adding a switch to the the compiler command is altering the source code of the IDE.

Thanks again PaulS.

I filed a bug report about this:

http://code.google.com/p/arduino/issues/detail?id=1112

and a helpful maintainer said that leaving the .ino file empty (put any comment, just to keep the compiler happy) and writing the code on a file with the .cpp extension on the same directory keeps the IDE away from messing with function prototypes. You must put the required #include's on the .cpp file too. On my case just

#include "Arduino.h"

This has another advantage: the compiler's output is related to the real file you wrote, not to some transformation, so any warning or error messages will mention the correct line number.

trurl:
I see quite a few C programmers here :slight_smile:

It's a fair cop!

Old habits die hard.