Goofiness with typedefs in the spark web IDE

I’m having an issue with the spark web IDE – I want to use a custom datatype in my program, and the only way I can do it is to put the datatype’s definition in a separate .h file. This works, but it feels hackish, and it’s a pain to share multi-file programs with other people using the web IDE. I’m looking for a way to declare a custom struct datatype in the same file as my functions. The full details are below. Any advice is welcome!


I’m writing a spark program, and I want to use a custom datatype, so I declare a struct:

typedef struct{
    unsigned char red, green, blue;
} color;

I want to use my newly declared color type as a parameter in a function,

void setPixel(int x, int y, int z, color col);

However, if I write an outline of a simple program

typedef struct{
    unsigned char red, green, blue;
}color;

void setup()
{
}

void setPixel(int x, int y, int z, color col)
{
    //do something here
}

It doesn’t compile in the web IDE. I get the following error:

listener_-_single_file.cpp:4:36: error: 'color' has not been declared
void setPixel(int x, int y, int z, color col);

I looked in the spark forums, and I found a mention of defining the struct in a separate .h file. So, I adjusted my program to:

#include "colors.h"

void setup()
{
}

void setPixel(int x, int y, int z, color col)
{
    //do something here
}

and created a separate colors.h file:

typedef struct{
    unsigned char red, green, blue;
} color;

Lo and behold, this works! I don’t know why it has to be this way, though. It feels clunky, and it makes it harder for me to share code, as it’s no longer a simple copy-and-paste-into-the-IDE operation.

I’m looking for a way to keep my struct definition in the main file, or at least understand why I can’t. Is this something funny about c++ that I don’t understand? Is this a quirk with the web IDE? What gives?

Hi @enjrolas

I think your problems are likely related to the Spark (Arduino-compatible) preprocessor that makes it so that new programmers don’t have to deal with function prototypes and other forward declarations.

You can turn it off with this pragma:

#pragma SPARK_NO_PREPROCESSOR

1 Like

If you just want to use your struct in this one file, just write

struct color {
    unsigned char red, green, blue;
}; 

// or I'd write - because I'm odd ;-)

struct color {
  uint8_t red;
  uint8_t green;
  uint8_t blue;
};
#pragma SPARK_NO_PREPROCESSOR

@BKO, that did it! thanks so much!

btw, apart from having to do function declarations, are there any downsides to turning off the preprocessor?

When you turn if off, you are just dealing with normal C/C++ rules, so just declaring everything before you use it and avoid Arduino syntax for constants (B11010111 vs 0b11010111).

Sweet, thanks!

Thanks @enjrolas for the heads-up, and thank you @bko for the workaround. Glad you’re not blocked Alex.

I’ve added an issue in our compile server repo so that this will get fixed in the future. Cheers!

Hey All,

This looks like an existing issue. When you use the build IDE and use the pre-processor, it tries to insert missing function declarations in your code that were left out. When you create a new type in the file, and then use it in your functions, the pre-processor isn’t smart enough to put your declarations after your typedef. If you put your typedef in another file, or add your missing function declarations, it should fix that issue as described. If you want it in the same file, write:

typedef struct{
    unsigned char red, green, blue;
} color;

//add this after your typedef in your main file here:
void setPixel(int x, int y, int z, color col);

otherwise the pre-processor does this:

//this was missing, inject it at the top after the includes:
//will throw error, since 'color' isn't defined yet.
void setPixel(int x, int y, int z, color col);

typedef struct{
    unsigned char red, green, blue;
} color;

edit: I’d love to solve this more magically, but I’m not aware of an obvious solution that doesn’t require unrolling and parsing dependency chains / reordering code. If someone has a better idea please let me know! :smiley:

Thanks,
David

2 Likes

That’s so good! Thanks for the in-depth explanation!

–me

1 Like