【发布时间】:2018-06-22 07:01:58
【问题描述】:
Windows 上的 Clang/LLVM 7 和 8 初始化一个内联静态数据成员每个 TU 一次。据我了解 C++17 这是不正确的。
虽然内联变量可以在多个 TU 中定义,但编译器和/或链接器必须确保它在程序中仅存在一次,因此只初始化一次。
以下小程序展示了使用 Clang/LLVM 会发生什么(在 Visual Studio 2017 和 2019 RC 中测试,带有 LLVM 编译器工具链扩展):
// 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
};
// TU1.cpp
#include "header.h"
int main()
{
S::a.f();
}
// TU2.cpp
#include "header.h"
// TU3.cpp
#include "header.h"
// TU4.cpp
#include "header.h"
这个程序打印:
ctor 010D4020
ctor 010D4020
ctor 010D4020
ctor 010D4020
f 010D4020
dtor 010D4020
dtor 010D4020
dtor 010D4020
dtor 010D4020
这是针对 A 的唯一一个对象的 四个 初始化(实际上每个 TU 一个),而不是正好一个(如 C++17 要求的那样)。 p>
程序应该打印:
ctor 010D4020
f 010D4020
dtor 010D4020
顺便说一句,这就是 MSVC 所做的。
这是 clang/LLVM 中的一个错误,对吧?
【问题讨论】:
-
Clang 使用了哪些编译选项?
-
和你之前问的the question有什么区别?
-
@xskxzr 另一个问题是指lld-link.exe,这个是link.exe。
-
@SergeBallesta -Xclang -std=c++17 -Xclang -flto -Xclang -O3
-
是否取决于优化选项?如果你删除
-flto,-Xclang的含义是什么?当您使用-std=c++17时,我真的认为这是一个 Clang 问题,但我认为您只需要使用相关选项即可填写错误报告。
标签: c++ clang c++17 llvm-clang