简体   繁体   中英

Compiling program containing extern “C”

I'm trying to use a makefile to compile a program someone else has written, using cygwin. I get a lot of error messages, of which many complain error: template with C linkage .

After searching around for a bit it seems the problem is connected to extern "C" . This line is contained in the file cygwin/usr/include/pthread.h , which is included with #include < pthread.h > in one of the headers. And when I remove this line most of the error messages disappear. But there are a few left, of the following sort:

/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

Does anyone know how to fix this? I would love to sit down and learn all this stuff in detail but I don't have time before I need this program running..

EDIT: Based on the exchange in the comments, the culprit was a header file in the build directory (Endian.h) that conflicted with a system include file /usr/include/endian.h. It was being included instead of the system header, and causing build issues. The files were in conflict because case is insignificant on Windows. The root cause was what was suggested in the original answer. The extern C construct was leaking into C++ code unintentionally, where templates were defined, causing the indicated error.

I would check for a "dangling" C linkage construct in your header files somewhere. This would be in code you wrote (not any of the system headers; those are likely safe).

Code in headers is wrapped with,

on top:

#ifdef __cplusplus
extern "C" {
#endif

and at bottom:

#ifdef __cplusplus
}
#endif

If the bottom part is missing, the effect of the top half extends into code in other headers unintentionally. This causes issues like you are encountering.

This problem arises when your compiler is compiling a mix of C and C++ code. The extern "C" syntax is a way to tell the C++ compiler that a C compiler will also need to access this function. The C compiler doesn't understand this use of extern, so typically you hide it like this:



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

However, you shouldn't go changing system headers, the chances of those being wrong are very slim. More likely one of your own headers is missing the closing brace above.

Similarity to the accepted answer, this was a nesting problem for me as well, but not with ifdef/endif , so I'm adding as a reference for others.

In my case, this error was caused by nested extern "C" constructs; one header file containing an extern "C" construct was included inside another extern "C" construct, causing nesting that confused the compiler/preprocessor.

File ah:

#ifdef __cplusplus
extern "C"{
#endif

#include "b.h"

#ifdef __cplusplus
}
#endif

File bh

#ifdef __cplusplus
extern "C"{
#endif

void someFunctionDeclaration();

#ifdef __cplusplus
}
#endif

Moving the #include "bh" outside of the ah extern "C" construct fixes the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM