Компиляция C с Objective-C и ошибкой компоновщика дубликатов символов (связана с iPhone) - PullRequest
4 голосов
/ 02 июля 2011

У меня есть следующий файл testf.h:

#ifndef TESTF_H_
#define TESTF_H_
int test(int what){
    return what;
}
#endif

Я включил / импортировал его в TestAppDelegate.h (который используется для других файлов .m в моем проекте xcode). Я получаю дубликат ошибки символа. Если я включил / импортировал testf.h в файл .m, который никогда не включался / не импортировался в другие файлы, тогда он работает нормально. Похоже, что #ifndef/#define/#endif не имеет никакого эффекта. Есть ли способ обойти это?

Спасибо

Ответы [ 3 ]

4 голосов
/ 02 июля 2011

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

#ifndef TESTF_H_
#define TESTF_H_
extern int test(int);
#endif

И затем файл .c (или, возможно, файл .m, если вы хотите использовать Objective-C вместо простого C), например:

int test(int what) {
    return what;
}

Заголовочный файл сообщит компилятору, что такое test, что он возвращает и какие аргументы он должен принимать; этой информации достаточно, чтобы компилятор организовал вызов test; это на самом деле больше информации, чем нужно компилятору, но некоторым из нас нравится, когда наши компиляторы выполняют некоторую проверку ошибок. Исходный файл C (после компиляции в объектный файл) сообщит компоновщику, к какому коду относится символ test.

Прямо сейчас у вас есть несколько глобально видимых экземпляров символа test, по одному на каждый файл, включающий ваш testf.h.

4 голосов
/ 02 июля 2011

Это определение функции, оно принадлежит файлу ac, cpp или m.

Этот популярный трюк с #defines защитит вас от ошибок компилятора (обычно для выживания циклических зависимостей #include.) Он не защитит от ошибки компоновщика.Именно поэтому люди помещают объявления в h-файлы и определения в c (или m) -файлы.

1 голос
/ 19 августа 2011

Другой вариант для простой функции - объявить ее inline:

inline int cNorm(float _amp) {
  return 42;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...