使用浮点文字初始化const int

时间:2012-06-07 03:56:27

标签: c++ c++11 constants

示例

int main()
{
    const int i = 1.0; // Notice I am assigning a double to an int here
    char a[i];
}

问题

使用g++ -O0 -Wall -pedantic -ansi -std=c++11编译上述代码不会产生任何错误(除了未使用的变量)。但是,如果我删除-std=c++11,我会收到以下警告:

  

警告:ISO C ++禁止可变长度数组

根据this SO question,我相信在C ++ 03中,代码无效。但是,有人可以解释规则在C ++ 11中的变化吗?

(这个问题是a previous question我回答的结果。)

1 个答案:

答案 0 :(得分:7)

数组绑定必须是一个整数常量表达式,参见8.3.4 [dcl.array] / 1(C ++ 03和C ++ 11中的相同措辞):

  

如果存在常量表达式(5.19),则它应为整数常量表达式,其值应大于零。

在C ++ 03中,除非转换为整数类型,否则浮点文字不能初始化整数常量表达式,请参见5.19 [expr.const] / 1的最后一句:

  

整数常量表达式只能涉及文字(2.13),枚举数,const变量或用常量表达式(8.5)初始化的整数或枚举类型的静态数据成员,非输入整数或枚举类型的模板参数,以及sizeof表达式。浮动文字(2.13.3)只有在转换为整数或枚举类型时才会出现。

这意味着在C ++ 03中i不是整数常量表达式,因此不能用作数组绑定。

GCC和Clang允许可变长度数组作为C ++ 03的扩展,因此它使用非常量绑定进行编译,但是会收到-pedantic的警告。更改常量的初始值设定项以将其强制转换为整数类型会使i成为有效的积分常量表达式:

const int i = (int) 1.0;

通过该更改,数组不再是可变长度,即使-pedantic也没有警告。

在C ++ 11 5.19 [expr.const] / 3中说:

  

文字常量表达式是文字类型的prvalue核心常量表达式,但不是指针类型。 整数常量表达式是整数或未整数枚举类型的文字常量表达式。

前面(相当冗长)的段落描述了核心常量表达式的规则,但基本上在C ++ 11中,双初始化器不会阻止i成为核心常量表达式,即使没有强制转换,所以它是一个整数常量表达式,因此是一个有效的数组绑定,所以没有警告。