I can't use my own type in the function prototype

Programming, for all ages and all languages.
Post Reply
User avatar
mrjbom
Member
Member
Posts: 301
Joined: Sun Jul 21, 2019 7:34 am

I can't use my own type in the function prototype

Post by mrjbom »

Hi.
I try to use the structure in my project, but I run into problems.

I have 2 files, lfbmemory.h(also have lfbmemory.c) and more.h (also have more.c).
In lfbmemory.c this structure was created.

Code: Select all

typedef struct ssfn_text_cursor {
    uint32_t x;
    uint32_t y;
    uint32_t context_index;
} __attribute__((packed)) ssfn_text_cursor_t;
In the file more.h I declare a function prototype that works with this structure.

Code: Select all

extern void show_base_info(ssfn_text_cursor_t* text_cursor);
But I get the following error when compiling lfbmemory.c

Code: Select all

Build ./source/lfbmemory/lfbmemory.c
In file included from ./source/lfbmemory/../memory/memmmu/../memdetect/memdetect.h:9:0,
                 from ./source/lfbmemory/../memory/memmmu/memmmu.h:9,
                 from ./source/lfbmemory/lfbmemory.h:9,
                 from ./source/lfbmemory/lfbmemory.c:1:
./source/lfbmemory/../memory/memmmu/../memdetect/../../more/more.h:13:28: error: unknown type name ‘ssfn_text_cursor_t’
 extern void show_base_info(ssfn_text_cursor_t* text_cursor);
Here(see lfbmemory and more folders) you can find the full versions of these files, which may help.
Thanks.
nullplan
Member
Member
Posts: 1766
Joined: Wed Aug 30, 2017 8:24 am

Re: I can't use my own type in the function prototype

Post by nullplan »

Oh, oh, you are creating a tangled web of dependencies. So more.h depends on lfbmemory.h (for the type declaration), but also, lfbmemory.h depends on more.h (because more.h is included in lfbmemory.h). This is a circular dependency you should cut ASAP. See, what happens is that lfbmemory.h includes memmu.h at the start, which includes memdetect.h, which includes more.h. more.h would like to include lfbmemory.h, but it can't, because the include guards are active. So that last include does nothing and the type remains undeclared by the time the compiler sees the prototype. Removing the include guards would not really help; you'd get double-definition errors instead. What you can try to do is restructure the header files so that you get a dependency tree again (instead of a cyclic graph), for instance by moving that structure definition into a new header file that both more.h and lfbmemory.h can depend on.

If the dependency structure truly must be this way, one workaround you have is to use incomplete types, which is enough for pointer declarations. So in more.h you write:

Code: Select all

struct ssfn_text_cursor;
void show_base_info(struct ssfn_text_cursor*);
And, boom, at least the include dependency is gone.
Carpe diem!
User avatar
mrjbom
Member
Member
Posts: 301
Joined: Sun Jul 21, 2019 7:34 am

Re: I can't use my own type in the function prototype

Post by mrjbom »

nullplan wrote:Oh, oh, you are creating a tangled web of dependencies. So more.h depends on lfbmemory.h (for the type declaration), but also, lfbmemory.h depends on more.h (because more.h is included in lfbmemory.h). This is a circular dependency you should cut ASAP. See, what happens is that lfbmemory.h includes memmu.h at the start, which includes memdetect.h, which includes more.h. more.h would like to include lfbmemory.h, but it can't, because the include guards are active. So that last include does nothing and the type remains undeclared by the time the compiler sees the prototype. Removing the include guards would not really help; you'd get double-definition errors instead. What you can try to do is restructure the header files so that you get a dependency tree again (instead of a cyclic graph), for instance by moving that structure definition into a new header file that both more.h and lfbmemory.h can depend on.

If the dependency structure truly must be this way, one workaround you have is to use incomplete types, which is enough for pointer declarations. So in more.h you write:

Code: Select all

struct ssfn_text_cursor;
void show_base_info(struct ssfn_text_cursor*);
And, boom, at least the include dependency is gone.
Yes, it's all right now. Thanks.
Post Reply