Unexpected error when function argument is a Class pointer

Hello,

I'm receiving an error I wouldn't expect in the Arduino IDE. When I compile the following code in Arduino 1.8.7 for the Arduino UNO:

class Class1 {};
void function1(Class1* c) {}

class Class2 {};
void function2(Class2* c) {}

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

I get the error:

sketch_dec04b:8:16: error: variable or field 'function2' declared void

 void function2(Class2* c) {}

                ^

sketch_dec04b:8:16: error: 'Class2' was not declared in this scope

sketch_dec04b:8:24: error: 'c' was not declared in this scope

 void function2(Class2* c) {}

                        ^
exit status 1
variable or field 'function2' declared void

If I delete the argument from "function1" (i.e. delete "Class1* c"), it compiles without errors.
If I delete the argument from "function2" (i.e. delete "Class2* c"), it also compiles without errors.
If I change the argument in "function2" from "Class2* c" to "Class1* c", so both functions take the same class as arguments, it compiles without errors.

Incidentally, if I replace one or both of the pointers (*) with a C++ style pass by reference (&), similar errors occur for all the above permutations.

The errors were only tested in the Arduino 1.8.7 IDE when compiling for the "Arduino UNO", "Arduino Due", and the "Teensy 3.6".

Any ideas what the cause might be? And, ideally, how I should solve it?

Thanks!

Thanks for providing a nice MCVE!

Before compiling, the Arduino IDE (actually arduino-builder) automatically generates function prototypes for any function in a .ino file that doesn't already have a prototype. Generally, arduino-builder does a very good job of this but in some rare cases it messes up. This is one of those cases.

If you turn on verbose output during compilation in File > Preferences and then examine the output, you can find the location of the temporary build folder. If you look in the sketch subfolder of that build folder, you will find the .ino.cpp file which is the sketch .ino files after function prototype generation. For this code, it looks like this:

#include <Arduino.h>
#line 1 "E:\\electronics\\arduino\\temp\\sketch_dec04b\\sketch_dec04b.ino"
#line 1 "E:\\electronics\\arduino\\temp\\sketch_dec04b\\sketch_dec04b.ino"
class Class1 {};
#line 2 "E:\\electronics\\arduino\\temp\\sketch_dec04b\\sketch_dec04b.ino"
void function1(Class1* c);
#line 5 "E:\\electronics\\arduino\\temp\\sketch_dec04b\\sketch_dec04b.ino"
void function2(Class2* c);
#line 7 "E:\\electronics\\arduino\\temp\\sketch_dec04b\\sketch_dec04b.ino"
void setup();
#line 8 "E:\\electronics\\arduino\\temp\\sketch_dec04b\\sketch_dec04b.ino"
void loop();
#line 2 "E:\\electronics\\arduino\\temp\\sketch_dec04b\\sketch_dec04b.ino"
void function1(Class1* c) {}

class Class2 {};
void function2(Class2* c) {}

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

So now the cause of the mysterious error is clear. The solution is to manually add the function prototypes in the correct locations.

The function prototype generation system is in the process of being completely reworked and moved to a dedicated tool named arduino-preprocessor. This preprocessor is already in use in the Arduino IDE beta build. If you compile your code with the beta build there is no error so it is correctly handling the prototype generation. For this reason, I don't think it's necessary to notify Arduino of the problem.

Probably has something to do with the Arduino IDE's annoying automatic prototype generation. This works:

class Class1;
class Class2;

class Class1 {};
void function1(Class1* c) {}

class Class2 {};
void function2(Class2* c) {}

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

Your original code compiles fine in a less "helpful" IDE like Eclipse / Sloeber.

Edit:
@pert beat me to it. At least it appears I was on the right track.

Wow! Thanks "pert" and "gfvalvo", I was expecting to wait days for an answer.

I think I'll stick to using prototypes with the "stable" IDE release, in case the beta release causes me more issues.

But, I'm happy to learn that the behind-the-scenes magic of prototype generation is going to become more magical. I also didn't think to check the temporary build folder, but will certainly look there from now on.

  • Thanks again!

You're welcome.

I think it's a good idea not to use the beta build of the Arduino IDE for everyday use. arduino-preprocessor does have some known bugs that will need to be fixed before it's ready for a production release. The Arduino IDE beta build is primarily intended for beta testing.