2016-12-23 3 views
-3

У меня есть ниже структура проекта:Неполного типа в C структуру

файл - ах

#pragma once 

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

файл - ЬН

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

файл - Ьс

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

на компиляция bc с использованием gcc -c b.c, it бросает следующую ошибку

file best_fit_mm has incomplete data type

Я включил a.h до того b.h, поэтому порядок выглядит собственно мне.

Удивительно, но если я включаю a.h внутри b.h, все будет решено.

+0

@SouravGhosh исправил опечатку в вопросе –

+0

ли «хиджры» и полные файлы «b.h»? Нет ли охранников? – peper0

+0

@ peper0 Я использовал #pragma один раз в обоих из них –

ответ

2

Компилятор должен знать всю схему каждого типа данных. Например. каждое поле в агрегатах, его смещение (см. offsetof), его размер (см. sizeof), его выравнивание (см. alignof) и его тип.

Так что компилятор должен знать все struct a (все поля там), чтобы выяснить расположение struct b (и это должно быть известно в точке определения в struct b).

На практике вам лучше добавить #include "a.h" рядом с началом вашего заголовка b.h. Конечно, вы хотите добавить include guards в свои файлы заголовков.

Кстати, я предпочитаю, чтобы избежать множества мелких заголовков, и я предпочитаю иметь несколько больших, возможно, даже один единственный общий заголовок для небольшого проекта (который вы можете предварительно компилировать с gcc см this ответа)

Иногда, чтобы отлаживать ошибки, связанные с препроцессором, вы можете попросить получить предварительно обработанную форму (например, используя gcc -C -E source.c > source.i, затем посмотрите с редактором или пейджером внутри source.i).

+1

Это правда, «вам лучше добавить». Однако он должен компилироваться и в том случае, о котором спрашивает автор. – peper0

+0

Ваши предпочтения беспокоят модульные тесты. – SergeyA

0

Если файл b.h использует элементы образуют файл a.h, то вы должны, по определению, включают в себя a.h в b.h

+1

Я бы хотел прокомментировать мое собственное сообщение: это не ответит на вопрос П. К моему пониманию '# include', предположим, что вы копируете и вставляете. И если они оба скопированы и вставлены по порядку в .c файле, почему он отказывается от компиляции правильно? Когда то же самое должно произойти, когда 'a.h' включен внутри' b.h'? –