10

我正在尝试使用makefile来编译其他人使用cygwin编写的程序。我收到很多错误消息,其中很多人抱怨error: template with C linkage

在搜索了一下之后,似乎问题与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

有谁知道如何解决这一问题?我很想坐下来详细学习所有这些东西,但是在我需要运行这个程序之前我没有时间。

4

3 回答 3

12

编辑:根据评论中的交流,罪魁祸首是构建目录 (Endian.h) 中的头文件,它与系统包含文件 /usr/include/endian.h 冲突。它被包含而不是系统标题,并导致构建问题。这些文件发生冲突,因为在 Windows 上大小写无关紧要。根本原因是原始答案中建议的。extern C 构造无意中泄漏到定义模板的 C++ 代码中,从而导致了指示的错误。

我会在某处的头文件中检查“悬空”C 链接结构。这将在您编写的代码中(不是任何系统标头;那些可能是安全的)。

标头中的代码用,

在上面:

#ifdef __cplusplus
extern "C" {
#endif

在底部:

#ifdef __cplusplus
}
#endif

如果缺少底部部分,则上半部分的影响会无意中延伸到其他标头中的代码中。这会导致您遇到的问题。

于 2013-08-28T18:13:28.677 回答
10

当您的编译器同时编译 C 和 C++ 代码时,就会出现此问题。extern "C" 语法是一种告诉 C++ 编译器 C 编译器也需要访问此函数的方法。C 编译器不理解 extern 的这种用法,所以通常你像这样隐藏它:



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

但是,您不应该更改系统标头,这些错误的可能性非常小。更有可能您自己的标题之一缺少上面的右括号。

于 2013-08-28T17:57:50.087 回答
3

与接受的答案相似,这对我来说也是一个嵌套问题,但不是ifdef/endif,所以我添加为其他人的参考。

就我而言,这个错误是由嵌套extern "C"结构引起的;一个包含构造的头文件包含extern "C"另一个 extern "C"构造中,导致嵌套混淆编译器/预处理器。

档案啊:

#ifdef __cplusplus
extern "C"{
#endif

#include "b.h"

#ifdef __cplusplus
}
#endif

文件 bh

#ifdef __cplusplus
extern "C"{
#endif

void someFunctionDeclaration();

#ifdef __cplusplus
}
#endif

移动结构的#include "b.h"外部a.h extern "C"解决了这个问题。

于 2016-12-05T06:43:07.440 回答