1

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?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Cyberflow
  • 1,255
  • 5
  • 14
  • 24
  • 2
    You made two different definitions of `Image` ... one is a typedef for `struct image *`, and the other is typedef for an unnamed struct. You can only typedef a name once. Maybe you meant `struct image { ...... };` in your c file – M.M Nov 21 '16 at 06:23
  • I have got to use the struct image * Image; that for sure I can't use the 2nd one. But what does the pointer * in the signature of the typder mean ? – Cyberflow Nov 21 '16 at 06:39
  • To add some info about this. The context is likely that one is trying to create a pointer to an incomplete type, sometimes called _opaque pointers_. This is a method of achieving true private encapsulation in C. If that is the case, it is better not to typedef it as a pointer though. Better to do `typedef struct image image` and force the caller to use the pointer syntax. – Lundin Nov 21 '16 at 08:01

1 Answers1

3

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.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • I will try to apply your solution; But what does the pointer * in the signature of the typder mean ? – Cyberflow Nov 21 '16 at 06:41
  • @Cyberflow That means, the alias is a pointer type, let me explan my answer a bit to cover that. – Sourav Ghosh Nov 21 '16 at 06:44
  • See [Is it a good idea to `typedef` pointers?](http://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers) to which the short answer is "No, unless they're function pointers". – Jonathan Leffler Nov 21 '16 at 07:00
  • @JonathanLeffler Just confirming sir, we're on the same side, right? ;) – Sourav Ghosh Nov 21 '16 at 07:04
  • 1
    I think so; my attitude is "thou shalt not use `typedef struct WhatNot *WhatNotPtr;` upon pain of … verbal abuse and complete shunning of code produced that uses such notations". It's not quite an absolute ban, but it is very close to it. (The exception could be where the external interface only ever treats the type as an opaque type and therefore only uses pointers and never needs to access the internals, but there's still resistance/reluctance even then.) – Jonathan Leffler Nov 21 '16 at 07:05
  • Don't forget that it's an exercice i'm doing to understand the functionnalities of the pointers on typedef. Thank you for the warning on good practice of not using pointers on typedef :) – Cyberflow Nov 21 '16 at 22:37