2016-12-23 1 views
-3

J'ai la structure ci-dessous du projet:type incomplet dans struct C

fichier

- ah

#pragma once 

struct best_fit_struct { 
    void *next; 
    size_t size; 
}; 
fichier

- bh

#pragma once 
typedef struct mm_t { 
    int type; 
    union { 
     struct best_fit_struct best_fit_mm; 
    } per_mm_struct; 
    void *memory; 
} mm_t; 
fichier

- bc

#include "a.h" 
#include "b.h" 

sur compiler bc en utilisant gcc -c b.c, il jette l'erreur suivante

file best_fit_mm has incomplete data type

J'ai inclus a.h avant b.h, de sorte que la commande semble bon pour moi. Étonnamment, si j'inclue a.h à b.h, les choses se résolvent.

+0

@SouravGhosh corrigé la faute de frappe dans la question –

+0

sont « a.h » et « b.h » dossiers complets? N'y a-t-il pas de gardes? – peper0

+0

@ peper0 J'ai utilisé #pragma une fois dans les deux –

Répondre

2

Le compilateur doit connaître la disposition complète de chaque type de données. Par exemple. chaque champ dans les agrégats, son décalage (voir offsetof), sa taille (voir sizeof), son alignement (voir alignof) et son type.

Ainsi, le compilateur a besoin de connaître tous struct a (tous les champs là-bas) pour déterminer la mise en page de struct b (et qui devrait être connu au point de définition de struct b).

En pratique, vous devriez ajouter #include "a.h" près du début de votre en-tête b.h. Bien sûr, vous voulez ajouter include guards dans vos fichiers d'en-tête.

BTW, ma préférence est d'éviter d'avoir beaucoup de petits en-têtes, et je préfère avoir quelques gros, peut-être même un seul en-tête commune pour un petit projet (que vous pouvez pré-compilation avec gcc, voir this réponse Parfois, pour déboguer les bogues liés au préprocesseur, vous pouvez demander d'obtenir le formulaire prétraité (par exemple, en utilisant gcc -C -E source.c > source.i puis en regardant avec un éditeur ou un pager à l'intérieur de source.i).

+1

C'est vrai, "tu ferais mieux d'ajouter". Cependant, il devrait également compiler dans le cas où l'auteur pose des questions. – peper0

+0

Votre préférence est troublante pour les tests unitaires. – SergeyA

0

Si le fichier b.h utilise les éléments forment fichier a.h alors vous devez, par définition, notamment dans les a.hb.h

+1

Je voudrais commenter sur mon propre post: Cela ne répond pas à la question d'OP. À mon avis '# include 'est censé être un copier-coller. Et si elles sont à la fois copiées et collées dans l'ordre dans le fichier .c, pourquoi refuse-t-elle de compiler correctement? Quand exactement la même chose est supposée se produire quand 'a.h' est inclus dans' b.h'? –