gpt4 book ai didi

c++ - 如何在不同命名空间中使用双重声明的 extern "C"函数进行 clang 构建(如 msvc 和 gcc)

转载 作者:搜寻专家 更新时间:2023-10-31 01:26:07 26 4
gpt4 key购买 nike

我有这个项目,其中包括另外两个项目,它们为同一个 DLL 提供 header 。在一个 header 中,声明被放入命名空间,而在另一个 header 中则没有。这适用于 GCC 和 MSVC,但我无法说服 clang 编译它。所以一个最小的例子是:

x.h:

#include <string>
#if defined __GNUC__
# pragma GCC system_header
#endif // __GNUC__

namespace XX {
struct Type {
std::string name;
};

extern "C" int Func(Type);
}

包括.h:

#include <string>
#if defined __GNUC__
# pragma GCC system_header
#endif // __GNUC__

struct Type {
std::string name;
};

extern "C" int Func(Type);

主要.cpp

#include "incl.h"
#include "x.h"

int main()
{
return 0;
}

G++ 发出警告,但使用 #pragma GCC system_header 将其关闭。那么,我怎样才能让 clang 在这样的环境中构建呢?

最佳答案

[dcl.link] At most one function with a particular name can have C language linkage. Two declarations for a function with C language linkage with the same function name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same function. ...

因此,::FuncXX::Func 必须引用相同的函数。但是您的两个声明具有不同的参数列表 - 一个采用 ::Type 参数,而另一个采用 XX::Type 参数。因此,它们不能是同一个函数,因此违反了引用规则,程序是病式的。永远

修复程序的几种方法:

  • 重命名 XX::Func::Func,使它们成为独立的函数。确保每个都有一个定义。
  • incl.h 中,包含 x.h 并将 ::Type 的定义替换为 using XX::Type 。因此每个 Type 都指代相同的类型,因此两个函数名称都指代相同的函数。确保只有一个定义。
  • x.h 中,包含 incl.h 并将 XX::Type 的定义替换为 using ::Type 。实现与上述相同。

后者是一些标准库实现如何实现 <cstdlib> 及其 friend 的方式。它们包含相应的 C 标准库 header (在 <stdlib.h> 的情况下为 <cstdlib> ),它在全局命名空间(C 中唯一的“命名空间”)中声明所有内容,然后它们将所有标准函数和类型选择到 std 命名空间和 using ::whatever 中。


附言不要使用 #pragma GCC system_header(除非您正在编写系统 header )。它将抑制所有警告(#warning 指令产生的警告除外)。

关于c++ - 如何在不同命名空间中使用双重声明的 extern "C"函数进行 clang 构建(如 msvc 和 gcc),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55867172/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com