I'm trying to write a generic template for Print for an Arduino project. In doing so, I encountered a compiler error I didn't understand, so I made a minimum reproducible example.
template <typename T, typename... T2>
void print_all(Print* const (&ps)[2], T v1, T2... v2) {
ps[0]->print(v1);
ps[0]->flush();
ps[1]->print(v1);
ps[1]->flush();
print_all(ps, v2...);
}
void print_all(Print* const (&ps)[2]) {
return;
}
void setup() {
print_all({&Serial1, &Serial2}, 1.0, "abc", 5ul);
}
void loop() {
}
The error I get is error: expected ')' before ';' token with no line number information. If I insert an empty line at the start of the file, the compiler error changes to
error: expected ')' before ';' token
1 |
| ^
| )
I tried this with avr-gcc version 7.3.0 (official arduino avr board) and 14.1.0 (using arch linux arduino avr boards) and get the same error either way.
I experimented for a while, and eventually put the code on Compiler Explorer using avr-gcc instead of Arduino IDE to compile. I had to provide some stubs to make everything compile, but it seems to work as I would expect. So why does my code work on compiler explorer, but not in the Arduino IDE?
code with supporting method stubs
class Print{
public:
virtual void print(unsigned long i) {
}
virtual void print(double i) {
}
virtual void print(const char* i) {
}
virtual void flush() {
}
};
class Serial: public Print {};
Serial serial1 = Serial{};
Serial serial2 = Serial{};
template <typename T, typename... T2>
void print_all(Print* const (&ps)[2], T v1, T2... v2) {
ps[0]->print(v1);
ps[0]->flush();
ps[1]->print(v1);
ps[1]->flush();
print_all(ps, v2...);
}
void print_all(Print* const (&ps)[2]) {
return;
}
int main() {
Print* const ps[] = {&serial1, &serial2};
print_all(ps, 1.0, "abc", 5ul);
}
-std=gnu++11so its on. I omitted the part of the error message that has the path to the file in which the error occurred, but there's no new or interesting information there, just a repetition of the same cryptic error message-std=c++11and refer to What are the differences between -std=c++11 and -std=gnu++11?