g++ variadic template issue

天涯浪子 提交于 2020-01-11 04:40:07

问题


So I gave this program to g++ and clang (both on 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 outputs s = aaaaaaaaaaaaaaaa (as expected).

g++ (versions 5 until 8) outputs s = s = aaaaaaaa (pretty unexpected).

This doesn't happen if you don't use the variadic template (if you remove all the <> code and inline the character list to initialize A::s.

It also doesn't happen if you replace the std::string by a character array (and use A<Cs...>::s = {Cs...} instead).

Is this code not meant to be, or is it a compiler bug?


回答1:


Your code is incorrect. The important part of the standard is 6.6.3/1 [basic.start.dynamic] in N4659:

Dynamic initialization of a non-local variable with static storage duration is unordered if the variable is an implicitly or explicitly instantiated specialization [...]

Because the initialization is not ordered, you cannot rely on the order of destruction. Any order is legal, regardless of order of construction. See 6.6.4/3 [basic.start.term]

gcc is thus allowed to destroy s before it destroys a, which is what happens and causes the weird output. Live.



来源:https://stackoverflow.com/questions/50339063/g-variadic-template-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!