Forward Declaration of Structs

I am trying access members of a struct from a separate file included in my project, but keep getting the following error:

error: invalid use of incomplete type 'data_t {aka struct _data_t}'

I have boiled this down to a simple sketch (attached), which consists of 3 files in the root directory.

------ sketch.ino ------

#include "defines.h"

static data_t *data = NULL;

void setup() {
  
  Serial.begin(115200);
  Serial.println(data->message);
}

void loop() {

}

------- defines.cpp --------

struct _data_t
{
    char length;
    char message;
};

-------- defines.h ----------

typedef struct _data_t data_t;

What am I not understanding about the compilation process, or just general C++ programming here?

Any help very much appreciated.

sketch_dec05a.zip (2.54 KB)

Just declare the struct in the header (defines.h):

struct data_t
{
    char length;
    char message;
};

This is only a declaration of a type, not a definition of a variable, so it can be in the header (i.e., it can be included multiple times without causing a "multiple definition" link error).

And you no longer need the typedef for struct types. They are really like a class now.

Thanks for the response -dev.

I didn't explain the full picture, I am trying to port a fairly large library which was originally written in C. It would be nice if I didn't have to edit the source code.

But I will try this out!

I am trying to port a fairly large library which was originally written in C. It would be nice if I didn't have to edit the source code.

Your library is wrong. You have to declare the struct in the header file.

And porting always requires editing.

-dev:
Your library is wrong. You have to declare the struct in the header file.

And porting always requires editing.

You don't have to declare a struct in a header file. Some libraries "hide" structure definitions behind opaque pointers, but that means the user's code cannot access any struct members (which is the point of doing this). Take C's FILE structure, for example. User code passes around pointers to FILE, but it doesn't access its member fields directly.

joextodd: if you want to hide your struct definition (as in the original code), you can't access data->message from sketch.ino because sketch.ino doesn't know what the struct looks like.

the user's code cannot access any struct members

Um... he is accessing the struct member. This is not an opaque type.

-dev:
Um... he is accessing the struct member. This is not an opaque type.

Of course. I was pointing out the purpose of using an opaque pointer (which the library is using). I also pointed out that he cannot access struct members as he was doing in sketch.ino with the library as it is.