【问题标题】:Compiling program containing extern "C"编译包含 extern "C" 的程序
【发布时间】:2013-08-28 17:42:56
【问题描述】:

我正在尝试使用 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

有谁知道如何解决这个问题?我很想坐下来详细了解所有这些东西,但我没有时间运行这个程序。

【问题讨论】:

  • 如果没有看到您尝试编译的实际代码,我们无能为力。
  • 不要修改pthread.h,这很可能是正确的,您需要弄清楚为什么会得到最可能不存在的原始错误。我要寻找的第一个候选者是宏。

标签: c++ c header-files extern


【解决方案1】:

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

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

标头中的代码用,

在顶部:

#ifdef __cplusplus
extern "C" {
#endif

在底部:

#ifdef __cplusplus
}
#endif

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

【讨论】:

  • @JonP.Harris 奇怪的是,正如我所提到的,我自己并没有编写代码,我很肯定它适用于其他人。我已经查找了您在标题中提到的代码,但到目前为止找不到。但是我怀疑作者使用的是 linux,而我使用的是 Windows,并且在谷歌上搜索似乎 pthread 和 cygwin 在 Windows 上可能存在一些问题?
  • @jorgen 你可以做的是查看预处理的输出。按原样运行编译器命令,但将“-c”选项替换为“-E”。输出应进入使用“-o”选项指定的文件。查看它,如果您愿意,请将文件粘贴到某处并在此处发布链接(如果您需要帮助)。
  • 感谢您的建议!问题是,查看生成文件我不太了解发生了什么,并且我找不到提到的包含 pthread.h 的文件,因此开始麻烦..
  • 您正在编译的目录中似乎有一个名为 endian.h 的文件。它干扰了您的构建。编译器包含该文件,而不是 /usr/include 中的标准文件。
  • 啊。大写是为什么它适用于其他人而不是你。在 Windows 上,大小写无关紧要。我可以编辑答案以反映这种交流。那你就可以接受了。
【解决方案2】:

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



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

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

【讨论】:

    【解决方案3】:

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

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

    文件 a.h:

    #ifdef __cplusplus
    extern "C"{
    #endif
    
    #include "b.h"
    
    #ifdef __cplusplus
    }
    #endif
    

    文件 b.h

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

    #include "b.h" 移到a.h extern "C" 构造之外可以解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-15
      • 2014-06-03
      • 2022-01-15
      • 2016-10-30
      • 1970-01-01
      相关资源
      最近更新 更多