首页 > 解决方案 > C++ 构造函数具有内部链接但未定义 [-Wundefined-internal]

问题描述

我收到来自clang9.0.0 版的恼人警告。

function '(anonymous namespace)::B::B' has internal linkage but is not defined [-Wundefined-internal]

g++给我一个类似的警告“X 已使用但从未定义”)

其他问题正在谈论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不被识别?

标签: c++clang++

解决方案


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)必须在使用它们的同一翻译单元中定义,因为它们不能在其他任何地方定义。如果函数在命名空间范围内声明为静态(静态在类范围内具有不同含义),或者如果它们在匿名命名空间中声明,则函数具有内部链接。


推荐阅读