[英]g++ and clang++ different behaviour with recursive initialization of a static member
Given the following code: 给出以下代码:
#include <iostream>
template <std::size_t N>
struct foo
{ static std::size_t value; };
template <>
std::size_t foo<0>::value = 0u;
template <size_t N>
std::size_t foo<N>::value = 1u + foo<N - 1u>::value;
int main()
{
std::cout
<< foo<3u>::value << ' '
<< foo<2u>::value << ' '
<< foo<1u>::value << ' '
<< foo<0u>::value << std::endl;
}
where the static member value
of the template struct foo
is recursively initialized, I get different outputs from g++: 在递归初始化模板struct
foo
的静态成员value
的地方,我从g ++获得不同的输出:
3 2 1 0
and from clang++: 从clang ++:
1 1 1 0
So seem that g++ initializes foo<N>::value
recursively using the initialized value of foo<N-1u>::value
where clang++ uses zero for foo<N-1u>::value
. 所以似乎g ++使用
foo<N-1u>::value
的初始化foo<N>::value
递归初始化foo<N-1u>::value
,其中clang ++对foo<N-1u>::value
使用零。
Two questions: 两个问题:
It is unspecified. 它没有具体说明。 Both compilers are right.
两个编译器都是对的。
Here are the relevant pieces from cppreference "initialization" . 以下是cppreference“initialization”的相关部分。
For all other non-local static and thread-local variables, Zero initialization takes place
对于所有其他非本地静态和线程局部变量,将进行零初始化
So for all these variables, they are zero when the program loads. 因此,对于所有这些变量,程序加载时它们为零。 Then:
然后:
After all static initialization is completed , dynamic initialization of non-local variables occurs in the following situations:
完成所有静态初始化后 ,在以下情况下会发生非局部变量的动态初始化:
1) Unordered dynamic initialization, which applies only to (static/thread-local) class template static data members and ... that aren't explicitly specialized.
1)无序动态初始化,仅适用于(静态/线程局部)类模板静态数据成员和......未明确专门化的。
And these variables match the criteria. 这些变量符合标准。 And then it says:
然后它说:
Initialization of such static variables is indeterminately sequenced with respect to all other dynamic initialization ....
对于所有其他动态初始化,这些静态变量的初始化是不确定的。
Which means that any sequence of initialization is fine. 这意味着任何初始化序列都可以。 Both compilers are correct.
这两种编译器是正确的。
To avoid the issue use constexpr
to force a "constant initialization" instead. 为避免此问题,请使用
constexpr
强制执行“常量初始化”。
It is Unspecified . 它是未指定的 。
You are using a construct where you reference a variable definition onto itself - perhaps somewhat analogue to saying int i = i-1
. 您正在使用一个构造 ,您可以在其中引用变量定义 - 可能有点类似于说
int i = i-1
。 In clang case, it is just using the generic template definition 在clang的情况下,它只是使用通用模板定义
template <std::size_t N>
struct foo
{ static std::size_t value; };//without specialization this will be ZERO initialized
because it hasn't seen 'itself' like normal template class or function would (as opposed to gcc case). 因为它没有像普通模板类或函数那样看到 '本身'(与gcc情况相反)。
To sum up: 总结一下:
1) Legit 1)合法
2) Unspecified 2)未指定
To avoid issues use constexpr and specialize the class template instead. 为了避免问题,请使用constexpr并专门化类模板。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.