2

i have those two struct thats come with their header files.

my struct number 1 is :

header files 'list.h':

typedef struct list * List;

source files 'list.c' :

struct list {
    unsigned length;
    char * value;
};

my struct number 2 is :

header files 'bal.h' :

typedef enum {START, END, MIDDLE, COMMENTS, CONDITIONS} TypeListBal;
typedef struct bal * Bal;

Source files 'bal.c' :

i've include those header files : 
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "list.h"

struct bal {
    TypeListBal type;
    List name;              // Name of the bal
    List attributes[];          // Array of type struct List
};

When i'm trying to use a function in my bal.c file like :

Bal createBal(List name){

char * search;
const char toFind = '=';
    search = strchr(name->value, toFind);

}

i'm getting an error at this line : search = strchr(name->value, toFind); saying : error: dereferencing pointer to incomplete type

I dont know why cause i've already include the list.h in my bal.c

I've read a lot over Stackoverflow saying that type of programmation it's called : opaque type which seems to be really nice but i dont get how to use my others headers file into other sources files. I thought that all i have to do it's to include my list.h in my bal.c files.

I'm compiling in gcc with this commamd : gcc -g -W -Wall -c bal.c bal.h

Thanks you very much !

Thapipo
  • 191
  • 3
  • 6
  • 16
  • A header file is just a convenient way to include common predefined code in many other source files... One catch -- if it's not in the header, it doesn't get included in any of the source files. Your struct definitions are not in the header files... – David C. Rankin Apr 09 '15 at 02:46
  • Don't include .h files in the compilation command. – James T. Smith Apr 09 '15 at 03:00
  • You should at least look at [Am I correct to assume one cannot forward declare a library's opaque pointer type?](http://stackoverflow.com/questions/27912385/) There are also other questions on the same general topic. The basic point is that if you have an opaque type such as `List` from `list.h`, you cannot access the members of that type outside the files where the exact structure definition is specified (which means only `list.c` can access the `value` or `length` members of a `List`). – Jonathan Leffler Apr 09 '15 at 03:01
  • suggest: 1) don't typedef struct definitions. 2) place the struct definitions in the header files. 3) bal.c needs to include the bal.h header file. 4) place the struct declarations (the actual struct objects) in the files that use them. – user3629249 Apr 09 '15 at 03:06

2 Answers2

3

The .h file only has the declaration of the struct and the typedef.

typedef struct list * List;

That doesn't give any clues as to what the members of the struct are. They are "hidden" in the .c file. When the compiler compiles bal.c, it has no way of knowing that struct list has a member value.

You can resolve this in couple of ways:

  1. Put the definition of struct list also in the .h file.
  2. Provide functions that can get/set the value of a struct list object.
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Your options number 2 say that i've to provide some getter/setters functions of a struct list. Do i inclue to function in my list.c or bal.c ? Cause we can't change or add anything to the header files, that why im a bit confuse and dont know how to deal with it. – Thapipo Apr 09 '15 at 02:56
  • The getters and setters must be provided in the .h file, otherwise you're back to square one: the compiler can't see the definitions. – James T. Smith Apr 09 '15 at 02:59
1

When you include header files, well, that's all you're doing. In your header files you have only the line:

typedef struct list * List;

Trying to use this structure from main causes the compiler to complain about an incomplete type, because from the perspective of the source file, this structure has no members. In fact it's not defined at all.

You need to put:

struct list;
typedef struct list * List;

In your header files. However, note that this process creates an opaque struct! Which means that doing e.g.

List l1;
l1->data = 0; //error

Is not allowed, because the compiler sees only what's included from the header file. In that compilation unit, no variables exist in the structure.

This can be used intentionally, to force users to go through getters/setters for your datatype. Something like

int data = ListStuff_Get_Item1(l1);

Can be done, but the ListStuff_Get_Item1() function needs to be declared in .h, and defined in .c.

James T. Smith
  • 410
  • 2
  • 9
  • I understand you answer but what if i can't add or change anything to my header files ? As you say my function Bal createBal(List name) is already declare in my .h file(bal.h) and im defining it in my .c (bal.c) But the 1st parameters of my functions is a struct List and as i understood, even if i did include list.h in my bal.c, the compiler dont know or doesn't know if List have members ! – Thapipo Apr 09 '15 at 03:02
  • Double check the assignment, ask your teacher if it's correct. Aside from that, you need to declare and define the structure before you typedef it. If you absolutely cannot modify the .h, then just declare it where it's needed in a .c file and #include the .h file after the definition. – James T. Smith Apr 09 '15 at 03:04
  • suggest adding a header file that contains all the struct definitions and eliminate those struct definitions from the .c files – user3629249 Apr 09 '15 at 03:10
  • Wow ! include all struct definition in a single header file and include this header file in all of my source files solve my problem. Thank a lot !! – Thapipo Apr 09 '15 at 23:42