2013-08-28 1 views
7

Я пытаюсь использовать make-файл для компиляции программы, которую кто-то написал, используя cygwin. Я получаю много сообщений об ошибках, из которых многие жалуются error: template with C linkage.Программа компиляции, содержащая extern «C»

После поиска понемногу, похоже, проблема связана с extern "C". Эта строка содержится в файле cygwin/usr/include/pthread.h, который включен в #include <pthread.h> в одном из заголовков. И когда я удаляю эту строку, большинство сообщений об ошибках исчезают. Но есть несколько левых, следующих видов:

/usr/include/pthread.h:67:5: error: previous declaration of ‘int pthread_atfork(void (* )(),void (*)(), void (*)())’ with ‘C++’ linkage 

/usr/include/sys/unistd.h:136:5: error: conflicts with new declaration with ‘C’ linkage 

Кто-нибудь знает, как это исправить? Мне бы очень хотелось сесть и изучить все это в деталях, но у меня нет времени, прежде чем мне понадобится эта программа.

+1

Мы не можем сделать ничего, чтобы помочь вам, не видя фактического кода, который вы пытаетесь скомпилировать. –

+6

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

ответ

8

EDIT: на основании обмена в комментариях виновником был заголовочный файл в каталоге сборки (Endian.h), который противоречил системе, включая файл /usr/include/endian.h. Он включается вместо заголовка системы и вызывает проблемы с сборкой. Файлы были в конфликте, потому что случай невелик в Windows. Основной причиной было то, что было предложено в первоначальном ответе. Конструкция extern C была непреднамеренно протекала в код C++, где были определены шаблоны, вызывая указанную ошибку.

Я бы посмотрел на конструкцию связи «болтаться» C в ваших файлах заголовков. Это было бы в коде, который вы написали (ни один из заголовков системы, вероятно, безопасен).

код в заголовках обернут,

на вершине:

#ifdef __cplusplus 
extern "C" { 
#endif 

и снизу:

#ifdef __cplusplus 
} 
#endif 

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

+0

@ JonP.Harris Странная вещь, поскольку я упомянул, что сам не написал код, и я уверен, что это работает для других людей. Я искал код, который вы упоминаете в заголовках, но не можете найти его до сих пор. Однако я подозреваю, что авторы используют linux, в то время как я использую Windows, и поиск по всему миру кажется, что могут возникнуть проблемы с pthread и cygwin на окнах? – jorgen

+1

@jorgen Что вы можете сделать, это посмотреть на предварительно обработанный вывод. Запустите команду компилятора как есть, но замените опцию -c на «-E». Выход должен идти в файл, указанный с опцией «-o». Посмотрите на это, и если хотите, вставьте файл где-нибудь и отправьте ссылку здесь (если вы хотите получить помощь). – Ziffusion

+0

Спасибо за предложение! Проблема в том, что, глядя на make-файлы, я не понимаю многое из того, что происходит, и я не могу найти упомянутый файл, который включает _pthread.h_, и поэтому начинается проблема. – jorgen

7

Эта проблема возникает, когда ваш компилятор компилирует код C и C++. Синтаксис extern «C» - это способ сообщить компилятору C++, что компилятор C также должен получить доступ к этой функции. C компилятор не понимает это использование экстерном, так как правило, вы скрыть это следующим образом:



    #ifdef __cplusplus 
    extern "C" { 
    #endif
void whatever();
#ifdef __cplusplus } #endif

Однако, вы не должны менять системные заголовки, шансы тех, ошибиться очень малы. Скорее всего, у одного из ваших собственных заголовков отсутствует закрывающая фигурная скобка выше.

1

Сходство с принятым ответом, это была проблема с гнездом для меня, а не с ifdef/endif, поэтому я добавляю в качестве ссылки для других.

В моем случае эта ошибка была вызвана вложенными конструкциями extern "C"; один заголовочный файл, содержащий конструкцию extern "C", был включен внутри другогоextern "C" Конструкция, вызывая вложенность, которая путала компилятор/препроцессор.

хиджры Файл:

#ifdef __cplusplus 
extern "C"{ 
#endif 

#include "b.h" 

#ifdef __cplusplus 
} 
#endif 

Файл б.ч

#ifdef __cplusplus 
extern "C"{ 
#endif 

void someFunctionDeclaration(); 

#ifdef __cplusplus 
} 
#endif 

Перемещение #include "b.h" за пределами a.hextern "C" конструкции исправляет эту проблему.