【问题标题】:Warnings when including C header file with C++ compiler使用 C++ 编译器包含 C 头文件时的警告
【发布时间】:2013-01-03 06:53:24
【问题描述】:

我有一些为 C99 程序编写的头文件。此标头包括所有函数定义,并且不与源文件配对。我将它包含在 C++ 文件中。

我的 C++ 编译器标志包括 -pedantic -std=c++11,它在头文件中给了我各种警告,例如“ISO C++ 禁止复合文字”和“ISO C++ 禁止可变长度数组”。显然,C++ 编译器将 C99 代码视为 C++。两个问题:

  1. 在尝试编写可在使用不同编译器的各种平台上正确运行的代码时,这是否是一个潜在问题?
  2. 解决警告并生成符合标准的代码的好方法是什么?我正在考虑使用 gcc 制作一个预编译的头文件,但对该过程知之甚少,无法确保我不会因为在 C++ 源代码中包含 C 预编译头文件而产生意外后果。

谢谢

【问题讨论】:

  • 试试 gnu++XX (XX = 98, 03, or 11);否则,您将不得不提出更清洁的解决方案。
  • @dans3itz:我正在使用 -std=c++11。是这个意思吗?
  • 1 => 是的。 2 => 创建 C99 代码的 C89 接口,并将 C++ 包含在 extern "C" 块中。顺便说一句,C99 本身就是一个可移植性问题。 Windows 中的 Visual c++ 不支持 C99。
  • 好吧,C++ 不支持很多 C99 特性。所以没有任何真正的方法可以使这个便携。 gnu++11 将为 C++11 提供一种扩展语言,使代码“工作”。这可能会让你度过这个阶段,但最终,你将需要 sep。 C++ 和 C99 模块,只需调用 C 接口。老实说,仅 C99 的可移植性就是一个问题。
  • Windows 上的可移植性是问题,而不是 C99。这就是制定标准的目的。

标签: c++ c gcc include


【解决方案1】:

在尝试编写可在使用不同编译器的各种平台上正确运行的代码时,这是一个潜在的问题吗?

是的。 GCC 可能只是给出警告,其他编译器(例如 Visual Studio 或带有其他选项的 GCC)很可能会给出错误。

解决警告并生成符合标准的代码的好方法是什么?

解决问题的正确方法是在 C 和 C++ 的公共子集中编写标头。使用 C99 特性(例如可变长度数组和复合文字)的函数和对象定义应移至单独的 C 源文件(使用 C 编译器编译!)。

【讨论】:

    【解决方案2】:

    要在 C++ 项目中包含纯 C 头文件 (*),您应该将 include 语句包装在 extern "C" 块中:

    // C++
    extern "C" {
    // C-code goes here
    #include "foo.h"
    }
    

    这是因为 C++ 对所有函数名执行名称修改以使重载工作。 C 不使用名称修饰,因此 C++ 解析 C 函数签名 with 名称修饰。

    请注意extern "C" 不会将编译器置于“C 模式”(没有这种模式,但您可能会错误地认为这条指令是这样的),它不会破坏函数名称(+ 更改调用约定并禁止重载;感谢 doomster 指出这些事情)。

    但是,如果您只包含 标头(使用内联实现),这应该不是问题,因为只有在您 链接 针对您的 C++ 项目的 C 源文件或库,因为在这种情况下函数名称不同。

    话虽如此,头文件应该使用C和C++的公共子集,用C编译器分别提取和编译这些函数的实现,不是 C++。然后,您(希望)可以将这两个部分链接在一起。很多 C 库已经有与 C++ 兼容的头文件,所以这是一个常见的过程。

    (*):通过使用语言功能的公共子集以及将所有内容包装在 条件 extern "C" 块中,一些头文件已经与 C 和 C++ 语言兼容。对于这样的header,你不应该使用这种方法,而只能用于那些没有这样一个块的headers。

    【讨论】:

    • 只是为了强调这一点,C++ 编译器永远不会将任何东西编译为 C 代码,即使在 extern "C" 子句中也不行!
    • @doomster 你是对的,它只是不会破坏名称。我想在回答中强调这一点,感谢您的提示。
    • 这还有其他方面,例如它可以改变函数调用约定(参数传递给/从函数的方式)。此外,您不能重载 extern "C" 函数,甚至不能将它们放入不同的命名空间(我相信除了匿名命名空间)。
    • @doomster 再次感谢;我编辑了我的答案。我希望有一天它是正确的;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    • 2021-12-15
    • 2012-05-15
    • 1970-01-01
    相关资源
    最近更新 更多