Reputation: 1129
So I'm screwing around with some Arduino (IDE version 1.8.9, FWIW) code, and I've discovered that typedefs seem not to work if placed after a function definition. For example, the following sketch fails to compile with error: 'foo' does not name a type
, but if you delete the first line there's no issue.
bool baz() { return false; }
typedef uint32_t foo;
foo bar() { return 1; }
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
Is this some nuance of how typedef works that I'm not familiar with, some Arduino-specific oddness, or is it just a bug?
(Note that the specific choice of uint32_t
doesn't matter here; the same behavior occurs with any type.)
Upvotes: 0
Views: 207
Reputation: 30494
The Arduino toolchain includes a preprocessor that attempts to make writing C++ easier. One of the things Arduino's preprocessor does is insert declarations for all of the functions in your sketch at the top of the file. That means that the actual C++ code passed to g++ looks like this:
#include <Arduino.h>
#line 1 "E:\\Documents\\Arduino\\sketch_jun16a\\sketch_jun16a.ino"
#line 1 "E:\\Documents\\Arduino\\sketch_jun16a\\sketch_jun16a.ino"
#line 1 "E:\\Documents\\Arduino\\sketch_jun16a\\sketch_jun16a.ino"
bool baz();
#line 3 "E:\\Documents\\Arduino\\sketch_jun16a\\sketch_jun16a.ino"
foo bar();
#line 5 "E:\\Documents\\Arduino\\sketch_jun16a\\sketch_jun16a.ino"
void setup();
#line 10 "E:\\Documents\\Arduino\\sketch_jun16a\\sketch_jun16a.ino"
void loop();
#line 1 "E:\\Documents\\Arduino\\sketch_jun16a\\sketch_jun16a.ino"
bool baz() { return false; }
typedef uint32_t foo;
foo bar() { return 1; }
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
As you can see, foo bar();
is declared before the name foo
is introduced by your typedef
.
To work around this, add your own declaration of bar
. Arduino's preprocessor will only add declarations of functions that you haven't declared yourself:
bool baz() { return false; }
typedef uint32_t foo;
foo bar();
foo bar() { return 1; }
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
As for why this isn't an issue when the typedef
is the first line of the sketch: it looks like Arduino's preprocessor lifts typedef
and using
declarations along with existing function declarations and class definitions up to the top of the file, before the function declarations it adds, but only if they appear before any function definitions (not counting class member functions defined inline in the class definition).
Upvotes: 4