g ++和clang ++的不同行为与静态成员的递归初始化 [英] g++ and clang++ different behaviour with recursive initialization of a static member
问题描述
给出以下代码:
#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;
}
递归地初始化模板结构 foo
的静态成员 value
,我从g ++得到了不同的输出:
where the static member value
of the template struct foo
is recursively initialized, I get different outputs from g++:
3 2 1 0
和从clang ++:
and from clang++:
1 1 1 0
似乎g ++使用 foo< N-1u> :: value
的初始化值递归地初始化 foo< N> :: value
,其中clang ++对 foo< N-1u> :: value
.
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 ++或clang ++?
推荐答案
未指定.两种编译器都是正确的.
It is unspecified. Both compilers are right.
以下是 cppreference初始化" 中的相关内容.
对于所有其他非局部静态变量和线程局部变量,初始化为零
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)无序动态初始化,仅适用于(静态/线程本地)类模板静态数据成员和……未明确专用.
1) Unordered dynamic initialization, which applies only to (static/thread-local) class template static data members and ... that aren't explicitly specialized.
并且这些变量符合条件.然后它说:
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.
为避免该问题,请使用 constexpr
强制执行恒定初始化".
To avoid the issue use constexpr
to force a "constant initialization" instead.
这篇关于g ++和clang ++的不同行为与静态成员的递归初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!