g ++可变参数模板问题

gus*_*gus 10 c++ g++ variadic-templates

所以我把这个程序给了g ++和clang(在Linux上,x86_64):

#include <iostream>

using namespace std;

template<char... Cs>
struct A {
  static const string s;
  static A a;
  ~A() {
    cout << "s = " << s << "\n";
  }
};

template<char... Cs>
const string A<Cs...>::s = {{Cs...}};

template<char... Cs>
A<Cs...> A<Cs...>::a;

int main(void)
{
  (void)A<'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'>::a;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Clang输出s = aaaaaaaaaaaaaaaa(如预期的那样).

g ++(版本5到8)输出s = s = aaaaaaaa(非常意外).

如果不使用可变参数模板,则不会发生这种情况(如果删除所有<>代码并内联字符列表以进行初始化A::s.

如果替换std::string字符数组(并A<Cs...>::s = {Cs...}改为使用),也不会发生这种情况.

这段代码不是故意的,还是编译器错误?

Bau*_*gen 8

您的代码不正确.该标准的重要部分是N4659中的6.6.3/1 [basic.start.dynamic]:

如果变量是隐式或显式实例化的特化,则动态初始化具有静态存储持续时间的非局部变量是无序的[...]

因为初始化没有排序,所以不能依赖于破坏的顺序.无论施工顺序如何,任何订单都是合法的.见6.6.4/3 [basic.start.term]

因此允许gcc s在它破坏之前被破坏a,这就是所发生的并且导致奇怪的输出..