Как предотвратить множественные определения в C?

36
задан Jordi 23 March 2009 в 09:46
поделиться

6 ответов

Вы на самом деле компилируете исходный код test.c дважды:

  • В первый раз при компиляции test.c сам,
  • Во второй раз при компиляции main.c, который включает весь test.c источник.

, В чем Вы нуждаетесь в Вашем main.c для использования эти test(), функция является простым объявлением, не его определением. Это достигается включением test.h заголовочный файл, который содержит что-то как:

void test(void);

Это сообщает компилятору, что такая функция с входными параметрами и типом возврата существует. Что делает эта функция (все в {, и }) оставлен в Вашем test.c файл.

В main.c, замените #include "test.c" [1 113].

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

#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED

void test(void);

#endif
84
ответ дан mouviciel 23 March 2009 в 19:46
поделиться
  • 1
    После большой работы я смог заставить исполняемый файл компилировать. Я должен был переместить много методов от.h до .cpp файлов. Этот doesn' t объясняют, почему об экспортируемых символах сообщили как неразрешаемый. – Gayan 19 March 2010 в 20:10

При использовании Visual Studio, Вы могли бы также сделать "#pragma однажды" наверху headerfile для достижения того же самого как "#ifndef..." - обертывание. Некоторые другие компиляторы, вероятно, поддерживают его также.... Однако не делайте этого: D Палка с #ifndef-wrapping для достижения совместимости кросс-компилятора. Я просто хотел сообщить, что Вы могли также сделать #pragma однажды, так как Вы, вероятно, встретите этот оператор вполне немного при чтении другого кода народов.

Удача с ним

4
ответ дан cwap 23 March 2009 в 19:46
поделиться

Включая реализацию файл (test.c) заставляет это предварительно ожидаться к Вашему main.c и соответствовал тут же снова отдельно. Так, функция test имеет два определения - один в объектном коде main.c и однажды в том из test.c, который дает Вам нарушение ODR. Необходимо создать заголовочный файл, содержащий объявление test, и включать его в main.c:

/* test.h */
#ifndef TEST_H
#define TEST_H
void test(); /* declaration */
#endif /* TEST_H */
4
ответ дан dirkgently 23 March 2009 в 19:46
поделиться

Подчеркивание помещается там компилятором и используется компоновщиком. Основной путь:

main.c
test.h ---> [compiler] ---> main.o --+
                                     |
test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe

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

void test(void);

Это позволяет компилятору знать, что он существует, когда main.c компилируется, но фактический код находится в test.c, тогда test.o.

Это - связывающаяся фаза, которая объединяется эти два модуля.

включением test.c в main.c, Вы определяете тест () функция в main.o. По-видимому, Вы тогда связываете main.o и test.o, оба из которых содержат функциональный тест ().

26
ответ дан paxdiablo 23 March 2009 в 19:46
поделиться
  • 1
    I' m немного колеблющийся для установки этого как ответа, потому что в связанном ответе, it' s показанный, что символы статических участников " can" быть экспортированным. Два экземпляра создаются для приложения и dll, но символ не дан как являющийся " unresolved" который является тем, что произошло в моем случае. Исправьте сообщение и I' ll принимают его. – Gayan 19 March 2010 в 20:12

Вы не должны включать другие исходные файлы (*.c) в .c файлы. Я думаю, что Вы хотите иметь заголовок ( ч) файл с ОБЪЯВЛЕНИЕМ тестовой функции, и иметь это - ОПРЕДЕЛЕНИЕ в отдельном.c файле.

ошибка вызывается повторными определениями тестовой функции (один в test.c и другом в main.c)

10
ответ дан Benjamin 23 March 2009 в 19:46
поделиться
  • 1
    Я думал, что dllimport был дополнительным. Я считал где-нибудь, что это был механизм, чтобы помочь компоновщику и компилятору выполнять лучшую оптимизацию, следовательно увеличивая производительность. Исправьте меня если I' m неправильно, так как мой опыт в этой области ограничен – Gayan 19 March 2010 в 19:21

Если Вы добавили test.c к своему Коду:: проект Блоков, определение будет замечено дважды - однажды через #include и однажды компоновщиком. Вы должны:

  • удаляют #include "test.c"
  • , создают файл test.h, который содержит объявление: пустой тест ();
  • включают файл test.h в main.c

4
ответ дан 23 March 2009 в 19:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: