Avertissement “paramètre a type incomplet”

J’ai ceci dans un fichier C:

struct T { int foo; }; 

le fichier C a un include dans un fichier h avec ces lignes:

 typedef struct TT; void listInsertFirst(T data, int key, LinkedList* ListToInsertTo); 

la fonction listInsertFirst est celle sur laquelle je reçois l’avertissement. Comment puis-je le réparer?

Comme nous l’avons découvert dans les commentaires, le problème était que la définition de la struct T s’est produite après la définition de T dans l’en-tête. Vous avez vraiment des choses en arrière ici. L’en-tête doit définir tous les prototypes de types et de fonctions et vos fichiers C doivent les utiliser.

Au lieu de cela, vous souhaitez modifier la signature de votre fonction d’insertion pour recevoir un pointeur sur vos données et leur taille. Ensuite, vous pouvez allouer de la mémoire pour les données, les copier et les stocker. Vous n’avez pas besoin d’un type spécifique, déclarez-le comme void * .

 void listInsertFirst(void *data, size_t data_size, int key, LinkedList* ListToInsertTo); 

Ensuite, l’appelant ferait quelque chose comme ceci:

 struct T { int foo; }; struct T x = { ... }; int someKey = ...; LinkedList *someList = ...; listInsertFirst(&x, sizeof x, someKey, someList); 

Lorsque vous incluez le fichier d’en-tête, le compilateur sait que T est une structure de taille inconnue et que listInsertFirst veut un comme premier argument. Mais le compilateur ne peut pas organiser un appel à listInsertFirst car il ne sait pas combien d’octets à appliquer à la stack pour le paramètre de T data , la taille de T n’est connue que dans le fichier où listInsertFirst est défini.

La meilleure solution serait de changer listInsertFirst pour prendre un T* comme premier argument afin que votre fichier d’en-tête dise ceci:

 extern void listInsertFirst(T *data, int key, LinkedList* ListToInsertTo); 

Ensuite, vous obtenez un pointeur opaque pour votre type de données T et, comme tous les pointeurs ont la même taille (du moins dans le monde moderne), le compilateur saura comment construire la stack lors de l’appel de listInsertFirst .

Êtes-vous sûr que c’est le premier paramètre qui pose problème? Pour être sûr, essayez de changer temporairement le type de paramètre de T à int . Plus que probablement, le troisième paramètre est en réalité le problème.

De nombreux compilateurs ne signalent pas très bien le problème de ce type de problèmes.

Essayez de déplacer la définition de la structure dans le fichier h, avant le typedef.

  1. Définir la struct T dans l’en-tête, pas dans le fichier .c;
  2. Choisissez des noms différents pour la structure et typedef.