Cyberflow Cyberflow - 16 days ago 7
C Question

Declaration of typedef with pointer

Learning the particularities of the C ANSI language this weekend and quite a challenge.

In an exercise I've got a header file that has a few declarations of signature of functions.

This one caught my attention:

typedef struct image * Image;


I tried this on my .c file :

typedef struct {
char nbrMagique[10];
unsigned long imgLarg;
unsigned long imgHaut;
unsigned long imgSeuilMax;
unsigned long **imageMatrice;
} Image;


But keep on constantly having error while compiling:

imagePGM.c:22:3: erreur: conflicting types for ‘Image’
} Image;


So I guess since I can't redefine the struct in the .c file and I can't touch the header either.

And to respect the "typedef struct image * Image;" in the .h header file I've got to create a dynamic 2 dimension table and point the pointer *image to it?

Am I missing out something in my reflexion?

But what does the pointer * in the signature of the typdef mean in the one of the .h file?

Answer

From the semantics of typedef, chapter §6.7.8, C11 document,

In a declaration whose storage-class specifier is typedef, each declarator defines an identifier to be a typedef name that denotes the type specified for the identifier [...]

So, basically, typedef is used to create an alias for a given type.

Also, to expand on that,

A typedef declaration does not introduce a new type, only a synonym for the type so specified. That is, in the following declarations:

typedef T type_ident;
type_ident D;

type_ident is defined as a typedef name with the type specified by the declaration specifiers in T (known as T), and the identifier in D has the type ‘‘derived-declaratortype- list T ’’.

In your code, you are trying to typedef two different types (i.e, struct image * and an unnamed struct) to a same alias name, which is the cause of the issue.

Solution: You don't need to typedef the structure declaration in your .c file, use a simple declaration, like

struct image {
    char nbrMagique[10];
    unsigned long imgLarg;
    unsigned long imgHaut;
    unsigned long imgSeuilMax;
    unsigned long **imageMatrice;
} ;   

That said, in general, typedef-ing pointers is considered a confusing coding style, which reduces readability, IMHO, avoid typedef-ing pointers.


Regarding the part

But what does the pointer * in the signature of the typedef mean?

It means, the new alias is pointer type. For the case,

 typedef struct image * Image;

both

 Image iPointer = NULL;

and

 struct image * againIPointer = NULL;

are same.