Разбиение программы на несколько файлов - получение ошибки «Переопределение; разные основные типы» - PullRequest
0 голосов
/ 17 октября 2010

Я хочу разбить мою программу на несколько файлов
1. main.c - это основная функция
2. definitions.h - содержит #define, typedef, прототипы функций
3. functions.c - содержит функцию (прототипы в definitions.h)

В дефиницияхs.h у меня есть typedef для структуры MyStruct , который используется в definitions.h & functions.c

Я сделал следующее:

в main.c, у меня #include "definitions.h" & #include "functions.c"
в functions.c у меня #include "definitions.h"

сейчас я получаю сообщение об ошибке C2371: 'MyStruct' : redefinition; different basic types (Это Visual Studio)

Теперь я не могу понять, почему я получаю эту ошибку! Спасибо!


Итак, вы предлагаете сделать следующее

main.c положить #include "definitions.h" (с typedef & #define и заголовками функций)

Теперь, как мне сказать компилятору, что ему нужно искать в файле functions.c определения функций?
Должен ли я поместить #include "functions.c" в definitions.h файл?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 17 октября 2010

Ваша первая проблема, как указано в моем комментарии, заключается в том, что вы включили исходный файл. Вы включаете только заголовки, так что есть прототипы и код компилируется, но вы не включаете другие файлы кода - они компилируются отдельно. Это не разрушает единственное преимущество, которое имеет отдельная компиляция: более быстрая перекомпиляция, поскольку между каждой компиляцией изменяется только несколько исходных файлов, и неизмененные файлы не нужно снова компилировать, поскольку файлы .obj все еще там.

Исправляя это, ваша проблема должна исчезнуть. Но не навсегда, только пока проект остается таким маленьким, и вы ничего не включаете несколько раз. Каждый заголовочный файл (ну, каждый файл, который вы включили - но это только заголовки) должен иметь «include guard», который предотвращает многократное включение файла (помните, #include "file" означает только «вставить содержимое file здесь»). перед компиляцией ") - main.c включает definitions.h и functions.c, но functions.c также включает definitions.h, поэтому содержимое definitions.h включается дважды, следовательно, все типы и прототипы функций фактически определяются дважды - что незаконно. В самом начале каждого заголовочного файла поместите что-то вроде этого:

#ifndef UNIQUE_HEADER_NAME_H
#define UNIQUE_HEADER_NAME_H

И в самом конце поставить #endif (некоторые предпочитают #endif //UNIQUE_HEADER_NAME_H после endif, для пояснения). Поэтому при первом включении файла UNIQUE_HEADER_NAME_H не определяется, поэтому файл включается как обычно , а UNIQUE_HEADER_NAME_H определяется. И в следующий раз, когда он будет включен, UNIQUE_HEADER_NAME_H уже определен, таким образом, препроцессор переходит к соответствующему endif (тому, который находится в конце, если вы не пропустили его в фактическом заголовке), и ничего не включается дважды.

2 голосов
/ 17 октября 2010

Первый - вам не нужно #include "functions.c" в main.c - определения уже существуют в definitions.h.Вообще говоря, вам следует избегать включения другого исходного файла.

Во-вторых, у вас, вероятно, нет #include -гвардей в вашем файле definitions.h, что могло бы вызвать эту проблему, поскольку вы включали оба functions.cи definitions.h в main.c, и functions.c включает в себя также definitions.h, что приведет к безумию множественного определения.

/* include guards */
#ifndef definitions_h_
#define definitions_h_
/* all of definitions.h content */
#endif

edit

Кроме того, в зависимости от используемых компиляторов вы можете использовать более простую директиву #pragma once.Visual C ++ поддерживает его, как и последние (> 3.4) версии GCC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...