我有一个来自9.0.0clang
烦人的警告。
function '(anonymous namespace)::B::B' has internal linkage but is not defined [-Wundefined-internal]
(g++
给我一个类似的警告"X已使用但从未定义")
其他问题正在谈论inline
或static
功能,但这不是我的情况。
这是一个最小的不工作示例:
:::.cpp:
#include "B.hpp"
namespace {
class A {
public:
bool foo(int& bar) {
B* b = new B(&bar);
return 0;
}
};
}
int main() {
return 0;
}
::: B.cpp ::
#include "B.hpp"
namespace {
B::B(int* b) : b(b) {};
}
:::
#ifndef B_HPP
#define B_HPP
#pragma once
namespace {
class B {
public:
B(int* b);
private:
int* b;
};
}
#endif // B_HPP
。编译方式
clang++ A.cpp B.cpp
以下是来自clang
的警告:
function '(anonymous namespace)::B::B' has internal linkage but is not defined [-Wundefined-internal]
我的问题是:为什么构造函数B
无法识别?
namespace {
这是一个匿名命名空间。匿名命名空间很特殊。每个翻译单元的匿名命名空间都是唯一的:A.cpp 中的匿名命名空间与 B.cpp 中的匿名命名空间完全不同。
B(int* b);
此行声明在匿名命名空间中声明的B
的构造函数。
B* b = new B(&bar);
此行调用 A.cpp 中的构造函数。除非定义(anonymous namespace of A.cpp)::B::B
,否则程序的格式不正确。
B::B(int* b) : b(b) {};
这定义了(anonymous namespace of B.cpp)::B::B
。请注意,此函数以及类本身与另一个翻译单元中的函数无关。
由于没有(anonymous namespace of A.cpp)::B::B
的定义,程序的格式不正确。
所有具有内部链接的函数(odr 使用的功能)都必须在使用它们的同一翻译单元中定义,因为它们无法在其他任何地方定义。如果函数在命名空间作用域中声明为 static (static 在类作用域中具有不同的含义),或者如果在匿名命名空间中声明,则函数具有内部链接。