【问题标题】:Initializing a const int with a floating point literal用浮点字面量初始化 const int
【发布时间】:2012-06-07 03:56:27
【问题描述】:

示例

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我回答的结果。)

【问题讨论】:

  • 您的意思是让i 成为双精度型,而不是整数型?
  • @Dave:不,这是故意的。请参阅上一个问题的链接。
  • FWIW,clang++ 3.0 不显示 VLA 警告。我没有 g++ 来测试它,但我想如果您将分配更改为 const int i = 1;,警告不会消失。是吗?
  • @jweyrich:在 clang++ 3.1 上使用 -pedantic 编译会给出类似的警告。如果您将其更改为const int i = 1;,警告就会消失。

标签: c++ c++11 constants


【解决方案1】:

数组绑定必须是整数常量表达式,参见 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 中说:

文字常量表达式是文字类型的纯右值核心常量表达式,但不是指针类型。 整型常量表达式是整型或无范围枚举类型的字面常量表达式。

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

【讨论】:

  • GCC 确实 not 警告错误的整数常量初始化。它警告使用 VLA 编译器扩展(C++11 不再使用它,因为在 C++11 中,数组可以由常量初始化)。
  • @Konrad,是的,刚刚编辑它以澄清我所说的“允许它”的意思
猜你喜欢
  • 1970-01-01
  • 2016-08-14
  • 2017-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多