x y*_*x y 13 c++ clang llvm-clang c++17
Windows上的Clang/LLVM 7.0.1 每个TU初始化一次内联静态数据成员.据我所知,C++ 17这是不正确的.
尽管可以在多个TU中定义内联变量,但编译器和/或链接器必须确保它在程序中仅存在一次,因此仅初始化一次.就像多重定义的内联函数一样,在程序中只存在一次.请参阅以下小程序:
// header.h
#include <iostream>
struct A
{
A() { std::cout << "ctor " << this << std::endl; }
~A() { std::cout << "dtor " << this << std::endl; }
void f() { std::cout << "f " << this << std::endl; }
};
struct S
{
inline static A a; // C++17 inline variable, thus also a definition
};
Run Code Online (Sandbox Code Playgroud)
// TU1.cpp
#include "header.h"
int main()
{
S::a.f();
}
Run Code Online (Sandbox Code Playgroud)
// TU2.cpp
#include "header.h"
Run Code Online (Sandbox Code Playgroud)
// TU3.cpp
#include "header.h"
Run Code Online (Sandbox Code Playgroud)
// TU4.cpp
#include "header.h"
Run Code Online (Sandbox Code Playgroud)
该程序打印:
ctor 010D4020
ctor 010D4020
ctor 010D4020
ctor 010D4020
f 010D4020
dtor 010D4020
dtor 010D4020
dtor 010D4020
dtor 010D4020
Run Code Online (Sandbox Code Playgroud)
这是A的唯一对象的四个初始化(实际上每个TU一个)而不是一个(如C++ 17要求).
该程序应打印:
ctor 010D4020
f 010D4020
dtor 010D4020
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这就是MSVC所做的.
这是clang/LLVM中的一个错误,对吧?
inline关键字的主要特征是它以两种方式修改了ODR规则:
在C ++ 17的唯一的另外的是,它也允许一个static数据成员声明是一个定义。而已。
一个static数据成员仍然具有相同的链接(外部你的情况),贮存期和使用寿命,并为所有实用目的的作品就像一个全局定义的变量。参见[class.static.data] / 6:
静态数据成员的初始化和销毁与非本地变量完全相同
从本质上讲,这意味着它应该与此相同:
struct A
{
A() { std::cout << "ctor "; }
~A() { std::cout << "dtor "; }
};
A a; // in one of the TU's
extern A a; // in all other TU's
Run Code Online (Sandbox Code Playgroud)
结论:
这是Clang中的错误。在static S::a必须进行初始化和销毁一次。
| 归档时间: |
|
| 查看次数: |
453 次 |
| 最近记录: |