I’m including my library’s header file, which defines a typedef page_count_t,
Yet, when I compile in the sparkulator, I get these errors:
/flashee.cpp: At global scope:
/flashee.cpp:28:24: error: variable or field 'assertPageIsReset' declared void
void assertPageIsReset(page_count_t page);
^
/flashee.cpp:28:24: error: 'page_count_t' was not declared in this scope
You’re coding well above my head, but when I get variable/type declaration errors, I try adding #include "application.h" at the top of my header. Does that help?
Thanks for the input. I had already included application.h. It’s just strange how I can use the symbol somewhere else and the compiler doesn’t complain.
Normally that would mean an include file problem with your header file. How are you including it in your .cpp file? In your library, the include should just be:
#include "flashee.h"
Do you have the usual protection against loading it twice in the .h file?
#ifndef _FLASHEE
#define _FLASHEE
//code here
#endif
I’m including it as described in the library - using the libname/header.h syntax.
I think the compiler is definitely finding the header, if I change the include name to a non-existent file, I get a fatal error.
Also, using #ifndef/#error, I see the symbol used to avoid double includes is defined, showing the header has been included. (I’d previously just used #pragma once in the header, but changed to the old style #ifndef/#define symbol just to be sure of inclusion.)
And this still fails at the class method. Yet the first use of page_count_t compiles fine. Replacing page_count_t with int in the class method signature also compiles fine.
Also, prefixing this with my namespace also makes it work.
ok, stripping it down as far as possible - this is the entire file I’m trying to compile:
#include "application.h"
typedef int myint;
myint count;
class Test {
myint a;
void f(myint b) {}
};
And it fails at Test::f() with
/flashee.cpp: At global scope:
/flashee.cpp:26:8: error: variable or field 'f' declared void
void f(myint b);
^
/flashee.cpp:26:8: error: 'myint' was not declared in this scope
Is there something strange the way the online IDE handles classes?
No namespaces, no includes. Just the code you see there. It should compile.
Ah, thanks, that’s a good idea. …yes putting it in a separate header makes it compile.
I was using this as a library example - the examples are expected to be single cpp file, which is why I put all the code in there. but of course, I can pull the bulk of it out to a header file.
Thanks for the tip - I think I can make it work now!
But it was a pretty obscure error. I wonder if the preprocessing is somehow broken for code containing classes and typedefs?
Just have to vent a little frustration with this. I’m trying to write examples for the library, yet each time I do I have to put most of the example code in a header file to get it to compile.
This makes writing library examples tedious, not to mention unclear for the library user since most of the example code isn’t in the CPP file. And it then pollutes the main library code with example headers.
I would really appreciate someone looking at this in more detail to see if the preprocessor can be fixed to handle more “advanced” code.
For example,
#if 0
asdf asdf - code to cause a compiler error
#endif
This works fine. But:
#if 0
asdf
void setup() {}
#endif
Fails with the error. So the inclusion of setup() affects the result.
Sorry to be so negative, but it’s irksome to be given a powerful tool like C++ running on a embedded wifi enabled 32-bit device and then have it broken and dumbed-down by the tools.
I don’t have access to the preprocessor code, otherwise I’d be glad to help fix it.
The Arduino pre-processor is meant to help new users by allowing them not worry about function prototypes or lots of other details of writing C/C++ that we take for granted. And it does help–most folks coming from Arduino don’t seem to know about any of these details.
But sometimes the pre-processor gets in the way of experienced folks who have experience with and the expectation of a certain C/C++ environment. The important thing to remember is that only the main sketch (*.ino) gets the Arduino pre-processor treatment, not the included library files.
If you are writing an example, you should try to write it from a naive user point of view, so the example should not have advanced concepts from the C/C++ world. That way the people coming from Arduino have a chance to see how to use your library in the environment that they are used to.
Thank you for posting the minimal breaking example. The pre-processor is most dumb about where in the code file it puts missing function declarations. It’s not smart enough to know if they should go before or after an include line, so if you add your void eraseAll(FlashDevice* dev); in the right place, it won’t try to add it itself. In general the pre-processor will leave things alone if nothing is missing, or if its’ a .h or .cpp file.
You can always tell the pre-processor to leave your code alone with:
#pragma SPARK_NO_PREPROCESSOR
If you want to send me code snippets that should compile but don’t, you can email me at david@spark.io, and I’ll add them to the buglist for the pre-processor as well.
@Dave, sorry to revive this old thread, but some of the problems still seem to persist and it hasn’t got anything to do with function prototypes.
And the same problem occures with Spark Dev.
I’d like to provide a port of Adafruits SPITFTBitmap example along with my port of the Adafruit_HX8357 library that can be built with Web IDE and Spark Dev.
But when compiling I always get 'File' was not declared in this scope messages, but File is declared in the SD-Card-Library which I include before first use of File.
I saw some threads mentioning this problem with other libs, but couldn’t transfer any of the hints to my problem.
What did I miss?
The bare minimum sketch (.ino) that shows this problem looks like this
If I put the function into a header file and include this (e.g. read16.h) it works,.
But since I can’t add this header into the SD-Card-Library where it would fit and it doesn’t fit with my HX8357 library this is not the way I want to got.
Examples should build without any other action than importing the required libraries off you go.
EDIT: I got it running with #pragma SPARK_NO_PREPROCESSOR as mentioned above, but I had a bad feeling about it, since I don’t know if ths might suppress some required preprocessing too.
But I still get why the preproc does cause this problem and why this can’t be cured.
Good question! I think what is happening is that the pre-processor sees you have a function defined that doesn’t have a declaration. Since C/C++ needs those, it tries to add one for you, but it isn’t super smart about where to put it, which results in the following:
//the pre-processor would place it here, it's not super smart yet.
uint16_t read16(File &f);
// This #include statement was automatically added by the Spark IDE.
#include "sd-card-library/sd-card-library.h"
//#include "read16.h"
uint16_t read16(File &f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
If you add that function declaration in the right place, it won’t re-add it for you, so if you change your code to the following, it should work:
// This #include statement was automatically added by the Spark IDE.
#include "sd-card-library/sd-card-library.h"
//#include "read16.h"
//add your function declaration here
uint16_t read16(File &f);
uint16_t read16(File &f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
void setup()
{
}
void loop()
{
}
But I thought, I tried this and it didn’t work, this was the reason why I posted the question in the first place.
Now I’ve tried it and it worked - so I guess I didn’t acutally do what I thought I did, when I tried it
Glad it worked the second time. The pre-processor again isn’t super duper smart, so if there was say, a single space between your function declaration and the ending semi-colon, it would fail, etc, etc.