Code uses SD Card library failed compilation

Is this a compilation bug or is it bad code practice made to look like a compilation bug?

FileError.ino has the specifics on this issue. I know how to work around this error. The error appeared after making simple mods to the code. But I was side tracked into other activities before getting back to it later the next day. Of course I had no idea how these innocuous changes broke the code. I couldn't remember what I had changed! While preparing dinner a light dawned on how to find the cause. Copy and start removing large chunks of code until it would compile. As it turned out I had moved an ISR closer to the head of the program. Where before it was below the SD Card support code included. The ISR had nothing to do with the SD Card library.

The support code includes "#include <SD.h>"
The ISR is as basic as it gets. "void myISR() {}" // did have a set global variable

FileError.ino (728 Bytes)

include.ino (35 Bytes)

Copulation Results in this error.

  • FileError:32:13: error: variable or field 'fooTwo' declared void

  • void fooTwo(File* log) {}

  •          ^~~~
    
  • FileError:32:13: error: 'File' was not declared in this scope

  • exit status 1

  • variable or field 'fooTwo' declared void

There are a number of posts along these lines. The preprocessor is reported to occasionally make mistakes in generating function prototypes.

I've run into the problem, and simply rearrange functions and #includes until it goes away. You could also try an earlier or later version of the IDE.

You need to include SD.h in order to define what a 'File' is, so that has to come first. Then, if the compiler gets the prototypes wrong, you can do it yourself.

#include <SD.h>;
void fooTwo(File*);  // correct declaration

void myISR() {}
#include "C:\<your path here>\include.ino"
void setup() {}
void loop() {}
void fooTwo(File* log) {}

I agree... however SD.H is included in the #include "C:<your path here>\include.ino"
file which is prior to "void fooTwo(File* log) {}"

That is why I thought it ought to work.

The automatic function prototype generation/insertion does not always work. It may be inserting those prototypes before your include so 'File' in not defined yet.

1 Like

if the 'include.ino' is in your sketch folder it will be included twice. Once because of the #include and once because it is a .ino file in your sketch folder. If you are going to #include it , rename it to 'include.h'.

If the types in your function declaration are not defined before the automatically generated function prototypes (because you have a function defined before your #include statements) you can work around the problem by adding a manual prototype:

void myISR() {}

#include <SPI.h>
#include <SD.h>
void fooTwo(File* log);

void setup() {}
void loop() {}
void fooTwo(File* log) {}

The more conventional solution is to put your #include lines BEFORE your function declarations:

#include <SPI.h>
#include <SD.h>

void myISR() {}
void setup() {}
void loop() {}
void fooTwo(File* log) {}
1 Like