1

I need to define a Structure in on source file and also others sources should be able to see that. I declare struct in ONE source file and then extern declaration in header to include in other sources, but the compiler following error is there:

lcd.c(24): error:  #147: declaration is incompatible with "struct graph_obj arrow_right" (declared at line 45 of "lcd.h")

.C file

struct graph_obj
{
    const u16   *id;
    int x,y;
    u16 w, h;
};

u32 lcdid;

struct graph_obj btn0;
struct graph_obj btn1;
struct graph_obj btn2;
struct graph_obj btn3;

and then .h file

extern struct graph_obj
{
    const u16   *id;
    int x,y;
    u16 w, h;
};

extern u32 lcdid;

extern struct graph_obj btn0;
extern struct graph_obj btn1;
extern struct graph_obj btn2;
extern struct graph_obj btn3;

So, what should I do?

crashmstr
  • 28,043
  • 9
  • 61
  • 79
Beh
  • 35
  • 2
  • 6
  • 4
    can you post code? judging from what you write you are doing things wring. – wirm Oct 11 '13 at 17:00
  • What you should do is to show the actual code / line with the error in `lcd.c` and the corresponding declaration in the header file. – crashmstr Oct 11 '13 at 17:01
  • just added codes, tnx – Beh Oct 11 '13 at 17:06
  • use `typedef struct...` in h module, then `extern` that typedef'd struct in same .h module, then you can use that type'd struct to create instances in each .c module where it is needed. See answer below for coded example. – ryyker Oct 11 '13 at 17:10

2 Answers2

2
in header:  

typedef struct 
{
    const u16   *id;
    int x,y;
    u16 w, h;
}GRAPH_OBJ;


extern GRAPH_OBJ graph_obj, *pGraph_obj; 

In c modules:

GRAPH_OBJ graph_obj, *pGraph_obj;  

Similar to your code, except that here, you have created a new type (GRAPH_OBJ), and it will behave as any type that is extern'd. And, you do not have to completely re-create the struct definition, it is all contained in GRAPH_OBJ. By the way, Here is a good post on how to use externs correctly.

Community
  • 1
  • 1
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • You are welcome. By the way, I did not make clear one other benefit (although it is discussed clearly in the link) that because of using the extern modifier in this way, structures created this way have project visibility, i.e. members assigned values in one .c module, will be the same value in any other module where that structure is used. This can be good, but it is a double edged sword if not careful. – ryyker Oct 11 '13 at 17:27
  • good point, tnx. so let me ask another question. does not use extern declaration decreases the execution performance at all? – Beh Oct 11 '13 at 17:52
  • I don't think _using_, or _not using_ `extern` will cause the _execution_ performance to change, but it will cause the behavior of your program to be different. i.e., by using extern in the way it is used above, not only you are making the variable `GRAPH_OBJ` (your structure) available for use in every .c module, you are also enabling the values assigned to its members to be immediately visible in each .c module that is using that structure (as I said before). But, no. I do not see any reason for performance to be degraded by the use of `extern`. – ryyker Oct 11 '13 at 19:14
1

You need to declare and define structure in header file, then include this header into corresponding source. having header with all the prototypes and public structures definitions included into source is a good idea and a widely applied practice. As suggested in another answer, "header guards" is a must have.

EDIT: You defined the structure 2 times, thats where the error is from. extern is only valid for variables, not for prototypes.

wirm
  • 100
  • 5
  • what should I do instead? – Beh Oct 11 '13 at 17:08
  • @Beh, you should declare and define all prototypes(public structures, forward declaration, macros, etc) in header(lcd.h in your case). Dont forget to make include guards in headers, they are your friends. Then you include lcd.h to lcd.c. All the public stuff is already in lcd.h, and you should not declare them again in lcd.c, so, you put in lcd.c only things, that are "private" for lcd.c(inner structures, function definitions, inner macros, etc). – wirm Oct 11 '13 at 17:13