C++ 构造函数具有内部链接但未定义 [-Wundefined-internal]
C++ constructor has internal linkage but is not defined [-Wundefined-internal]
我收到来自 clang
版本 9.0.0 的恼人警告。
function '(anonymous namespace)::B::B' has internal linkage but is not defined [-Wundefined-internal]
(g++
给我一个类似的警告"X used but never defined")
其他问题都在谈论inline
或static
功能,但我不是这样。
这是一个最小的无效示例:
:::::::::::::::: A.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) {};
}
:::::::::::::::: B.hpp::::::::::::::
#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
,程序就是ill-formed.
B::B(int* b) : b(b) {};
这定义了 (anonymous namespace of B.cpp)::B::B
。请注意,此函数以及 class 本身与另一个翻译单元中的函数无关。
由于(anonymous namespace of A.cpp)::B::B
没有定义,程序是ill-formed.
所有具有内部链接的函数(即 odr-used)必须在使用它们的同一翻译单元中定义,因为它们不能在其他任何地方定义。如果函数在命名空间范围内声明为静态(静态在 class 范围内具有不同的含义),或者如果它们在匿名命名空间中声明,则函数具有内部链接。
我收到来自 clang
版本 9.0.0 的恼人警告。
function '(anonymous namespace)::B::B' has internal linkage but is not defined [-Wundefined-internal]
(g++
给我一个类似的警告"X used but never defined")
其他问题都在谈论inline
或static
功能,但我不是这样。
这是一个最小的无效示例:
:::::::::::::::: A.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) {};
}
:::::::::::::::: B.hpp::::::::::::::
#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
,程序就是ill-formed.
B::B(int* b) : b(b) {};
这定义了 (anonymous namespace of B.cpp)::B::B
。请注意,此函数以及 class 本身与另一个翻译单元中的函数无关。
由于(anonymous namespace of A.cpp)::B::B
没有定义,程序是ill-formed.
所有具有内部链接的函数(即 odr-used)必须在使用它们的同一翻译单元中定义,因为它们不能在其他任何地方定义。如果函数在命名空间范围内声明为静态(静态在 class 范围内具有不同的含义),或者如果它们在匿名命名空间中声明,则函数具有内部链接。