Возьмем пример моего проекта:
У меня есть 2 файла, file1.c и file2.c. Оба этих файла имеют заголовочный файл (file1.h и file2.h). У меня также есть файл struct.h, который содержит:
typedef struct {
char region[80];
int startDate;
int endDate;
int startTime;
int endTime;
} Schedule;
Оба заголовочных файла (file1.h и file2.h) включают struct.h, а main.c включает и file1.h, и file2.h. Допустим, это main.c:
#include <stdio.h>
#include "file1.h"
#include "file2.h"
int main() {
/* function from file1.h */
int num1 = sum(1, 3);
/* function from file2.h */
int num2 = mul(4, 5);
}
Теперь в main.c я получаю сообщение об ошибке: In included file: typedef redefinition with different types
. Я предполагаю, что ошибка связана с тем, что и file1.h, и file2.h объявляют свои собственные общие структуры из struct.h.
Есть идеи по решению проблемы?
Это очень распространенная проблема при включении других файловых юнитов, и решение состоит в том, чтобы всегда использовать включенные защитные элементы в вашем заголовочном файле, например.
// struct.h
#ifndef INCLUDED_STRUCT_H
#define INCLUDED_STRUCT_H
typedef struct {
char region[80];
int startDate;
int endDate;
int startTime;
int endTime;
} Schedule;
#endif
С этим include guard в вашем main.c
, даже если он включает в себя и file1.h
, и file2.h
, есть только определение struct
.
Стандартный способ решить эту проблему — заключить определения в struct.h
внутри директивы препроцессора #if
или #ifdef
, чтобы избежать дублирования определений, если файл включается более одного раза. Это обычно называют включенными охранниками.
структура.ч:
#ifndef STRUCT_H_INCLUDED
#define STRUCT_H_INCLUDED
typedef struct {
char region[80];
int startDate;
int endDate;
int startTime;
int endTime;
} Schedule;
#endif /* STRUCT_H_INCLUDED */
Вы должны использовать этот метод для всех включаемых файлов, чтобы предотвратить избыточные определения, которые во многих случаях вызывают ошибки компиляции.
Использование включает охрану. Это стандартный подход к предотвращению множественных проблем с включением. Глядя, если я могу найти дубликат. Если нет, ваша тестовая книга обязательно должна их обсудить.