内联变量的多重销毁

Multiple destruction of an inline variable

这是一个包含内联变量的头文件:

// inline.hpp
#pragma once

#include <iostream>

struct Test {
    ~Test() { std::cout << "deleted" << std::endl; }
};

inline const Test test;

...包含在两个 .cpp 文件中:

// usage.cpp
#include "inline.hpp"
// main.cpp
#include "inline.hpp"
auto main() -> int { return 0; }

此程序打印 "deleted" 两次,这是意外的。 我以为每个内联变量只有一个实例,所以我期望只有一个 "deleted".

这是编译器的错误吗?还是我做错了什么?

代码是用VS2017编译的

Is this a bug of compiler?

据我所知,是的。 GCC 和 Clang,(以及根据评论的 VS2019)只打印一次 "deleted"。

命名空间范围内的非易失性 const 内联变量具有外部链接。您描述的行为似乎暗示内部链接,这是编译器的错误行为。

为了完整起见,相关标准规则(来自最新草案,强调是我加的,括号中强调的部分是我加的):

[basic.link]

A name having namespace scope has internal linkage if it is the name of

  • ... explicitly declared static; [does not apply] or

  • a non-template variable of non-volatile const-qualified type, [applies...] unless

    • ...
    • it is inline or exported, [exception applies] or

... A name having namespace scope that has not been given internal linkage above [applies] and that is the name of

  • a variable; [applies] or

  • ...

has its linkage determined as follows:

  • if the enclosing namespace has internal linkage, the name has internal linkage; [does not apply]

  • otherwise, if the declaration of the name is attached to a named module ... [does not apply]

  • otherwise, the name has external linkage. [applies]