Compilers Never Lie

Just a quick note about an annoying behaviour I found in the Ardunio IDE + compiler + toolchain. I was writing the following task scheduler and started off with the typical typedef of a function prototype:

typedef void (*callback_t)(void);

struct task_t {
 long interval;
 int lastScheduled;
 int nextScheduled;
 boolean oneShot;
 callback_t callback;
};

void setup() {
}

void loop() {
}

void addInterval(int intervalMicros, callback_t f) { 
}

void addOneShot(int delayMicros, callback_t f) {
}

This kept on throwing the following compilation errors in the IDE:

Scheduler:6: error: 'callback_t' has not been declared
Scheduler:7: error: 'callback_t' has not been declared

Weird, since there’s not even a USAGE of callable_t on those lines.  Sniffing a bit deeper, I found that the IDE actually pre-compiles my program (called a “sketch”) into a temporary .cpp file, which contained the following:

#line 1 "Scheduler.ino"

#include "Arduino.h"
void setup();
void loop();
void addInterval(int intervalMicros, callback_t f);
void addOneShot(int delayMicros, callback_t f);
void run();
#line 3
typedef void (*callback_t)(void);

struct task_t {
 long interval;
 int lastScheduled;
 int nextScheduled;
 boolean oneShot;
 callback_t callback;
};

void setup() {
}

void loop() {
}

void addInterval(int intervalMicros, callback_t f) {
}

void addOneShot(int delayMicros, callback_t f) {
}

Ah ha! The damn sketch “pre-compiler” was automatically forward declaring my two functions addInterval() and addOneShot() and this was creating an undefined forward usage of callback_t. Thank you Arduino IDE.