C ++ 98大括号const标量初始化

时间:2013-12-18 16:07:32

标签: c++ gcc clang c++98

我偶然发现了我不理解的代码。这是它的简化版本:

template <int> struct A {};

int const i = { 42 };
typedef A<i> Ai;

int const j = 42;
typedef A<j> Aj;

此代码在C ++ 98模式下与GCC编译,但在Clang中不编译。 Clang产生以下错误:

$ clang -Wall -Wextra -std=c++98 -c test.cpp

test.cpp:4:11: error: non-type template argument of type 'int' is not an integral constant expression
typedef A<i> Ai;
          ^
test.cpp:4:11: note: initializer of 'i' is not a constant expression
test.cpp:3:11: note: declared here
int const i = { 42 };
          ^

据我所知,带有和不带花括号的int的初始化应该是等价的。 Clang正确地将i初始化为42,只是认为它不是编译时常量。

此代码在C ++ 11模式下编译良好。

是否有理由j被视为编译时常量而i不是?或者它只是Clang中的一个错误?

更新:我在此问题中在LLVM错误跟踪器中打开了ticket

3 个答案:

答案 0 :(得分:5)

是的,根据C ++ 98 8.5 / 13,两个声明都是等效的:

  

如果T是标量类型,则表示

形式的声明
T x = { a };
  

相当于

T x = a;

因此两个变量都是常量,并从常量表达式初始化,所以(据我所见)应该都可以用作常量表达式。

答案 1 :(得分:2)

编译器错误指出"template argument of type 'int' is not an integral constant expression"

int const i = { 42 };

根据98 standard,模板参数应属于此类别:

  

14.3.2 / 1

     

非类型非模板模板参数的模板参数应为以下之一:

     
      
  • 整数或枚举类型的整数常量表达式;或
  •   
     

...

并且整数常量表达式int const i的定义属于这一类:

  

5.19常量表达式

     

整数常量表达式只能包含文字(2.13),枚举数,常量变量或静态   数据成员

i的初始化(如Mike Seymour的帖子):

  

8.5 Initializers / 13

     

如果T是标量类型,则表示

形式的声明      

T x = {a};

     

相当于

     

T x = a;

现在基于this post const intint const的声明应该是相同的(在标准中找不到这个),使i成为 const变量即可。因此,无论初始化方法如何,i的任何用法都应该是一个整型常量表达式。看来clang中有一个bug。检查网络我找不到两个或多或少类似的错误报告:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666539

http://lists.cs.uiuc.edu/pipermail/llvmbugs/2011-March/017353.html

答案 2 :(得分:1)

我认为Clang是对的。初始化列表不是表达式。初始化聚合对象和基础对象之间存在差异。初始化POD对象时,可以将每个初始化程序视为const表达式。但是,当您处理基本类型时,初始化列表不是表达式,也不是const表达式。

在标准第14段中写道:

  

初始化程序是大括号括起来时,未定义源类型   或者当它是带括号的表达式列表