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")

其他问题都在谈论inlinestatic功能,但我不是这样。

这是一个最小的无效示例:

:::::::::::::::: 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 范围内具有不同的含义),或者如果它们在匿名命名空间中声明,则函数具有内部链接。