g ++可变参数模板问题

古斯

因此,我将此程序提供给了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;
}

Clang输出s = aaaaaaaaaaaaaaaa(按预期)。

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

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

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

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

眼睛的树

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

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

因为初始化没有顺序,所以您不能依赖销毁顺序。任何命令都是合法的,无论构造顺序如何。参见6.6.4 / 3 [basic.start.term]

因此,允许gcc在销毁s之前销毁它a,这是发生的并导致奇怪的输出。现场直播

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章