sketch_jun18a:3:9: error: variable or field 'vX' declared void
void vX(X * px) {}
^
sketch_jun18a:3:9: error: 'X' was not declared in this scope
sketch_jun18a:3:13: error: 'px' was not declared in this scope
void vX(X * px) {}
^~
sketch_jun18a:3:9: error: variable or field 'vX' declared void
void vX(X * px) {}
^
sketch_jun18a:3:9: error: 'X' was not declared in this scope
sketch_jun18a:3:13: error: 'px' was not declared in this scope
void vX(X * px) {}
^~
exit status 1
variable or field 'vX' declared void
As you can see, it moved the prototype for the vX function before the definition of the struct X. You can add your own prototypes for the function to prevent the Arduino preprocessor from messing it up, or you can move your structs and/or functions to a separate pair of .hpp/.cpp files, since the Arduino builder only adds prototypes in .ino files.
Well that explains why we have an error message but...
... it doesn't explain why struct Y gets put/left at the top, where it's good but then leaves struct X hanging about further down the code where it causes a problem.
I added a struct Z below structs Y and X and it also generates the same error. So why is the first struct okay?
I don't think it's moving the structs. So they aren't getting "left hanging about" anywhere.
Prior to the first function it's auto inserting all the function protoypes for all the other functions in the sketch.
Problem comes when those prototypes reference structs which haven't been declared yet.
I guess it is a bug. The IDE assumes either...
a) You define all your structs before your functions (not required, but quite a common coding pattern).
b) You supply your own function prototypes. Which by definition must come after any struct definitions they reference.
struct X {};
void vX(struct X * px) {} ////// ADDED THE 'struct' KEYWORD
void setup() {}
void loop() {}
The automatically generated prototype doesn't need the declaration of 'X' if it knows that 'X' is a 'struct'.
Gosh! What a game. I assume they modified the way pre-processing happens, compared with a traditional tool chain, to make it easy for the majority to do the majority of things but hey ho, I've been caught out a couple of times by things like this... not to worry its all fun.
acboother:
Gosh! What a game. I assume they modified the way pre-processing happens, compared with a traditional tool chain, to make it easy for the majority to do the majority of things but hey ho, I've been caught out a couple of times by things like this... not to worry its all fun.
Yes, it's intended to make C++ programming easier for non-programmers. They try to make it so you don't have to declare functions before you use them (by inserting prototypes at the top) and so you don't have to list all of the libraries you want the linker to link with (by recognizing "#include" lines as probable references to libraries) and so you don't have to learn how to do external references (by merging all your .ino files into a single file).