用浮点文本初始化const int [英] Initializing a const int with a floating point literal
问题描述
i = 1.0; //注意我将一个double赋值给这里的
char a [i];
}
问题
使用 g ++ -O0 -Wall -pedantic -ansi -std = c ++ 11
编译上述代码不会产生错误(除了未使用的变量)。但是,如果我删除 -std = c ++ 11
,我会收到以下警告:
警告:ISO C ++禁止可变长度数组
根据这个问题,我相信在C ++ 03,代码是无效的。但是,有人可以解释一下规则在C ++ 11中的变化吗?
(这个问题是上一个问题我回答。)
数组绑定必须是一个整数常数表达式,见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 allow可变长度数组作为C ++ 03的扩展,所以它编译为非常量绑定,但是你会收到 -pedantic
的警告。更改常量的初始值以将其转换为整数类型使 i
是一个有效的整数常量表达式:
const int i =(int)1.0;
使用该更改,数组不再是变量长度,即使使用 -pedantic
。
在C ++ 11中5.19 [expr.const] / 3说:
字符常量表达式是字面类型的核心常量表达式,但不是指针类型。
前面的(完全的)常量表达式冗长的)段落描述核心常量表达式的规则,但基本上在C ++ 11中,双初始化器不会阻止 i
是核心常量表达式,即使没有强制转换,它是一个整数常数表达式,因此有效的数组界限,所以没有警告。
Example
int main()
{
const int i = 1.0; // Notice I am assigning a double to an int here
char a[i];
}
Question
Compiling the above code with g++ -O0 -Wall -pedantic -ansi -std=c++11
gives no errors (except for an unused variable). However, if I remove -std=c++11
, I get the following warning:
warning: ISO C++ forbids variable length array
According to this SO question, I believe that in C++03, the code is invalid. However, can someone explain how the rule has changed in C++11?
(This question was a result of a previous question I answered.)
An array bound must be an integral constant expression, see 8.3.4 [dcl.array]/1 (same wording in C++03 and C++11):
If the constant-expression (5.19) is present, it shall be an integral constant expression and its value shall be greater than zero.
In C++03 an integral constant expression cannot be initialized by a floating literal unless cast to integral type, see the last sentence of 5.19 [expr.const]/1:
An integral constant-expression can involve only literals (2.13), enumerators,
const
variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, andsizeof
expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types.
This means that in C++03 i
is not an integral constant expression, so cannot be used as an array bound.
GCC and Clang allow variable-length arrays as an extension to C++03, so it compiles with a non-constant bound, but you get a warning with -pedantic
. Changing the constant's initializer to cast it to integral type makes i
a valid integral constant expression:
const int i = (int) 1.0;
With that change the array is no longer variable length and there is no warning even with -pedantic
.
In C++11 5.19 [expr.const]/3 says:
A literal constant expression is a prvalue core constant expression of literal type, but not pointer type. An integral constant expression is a literal constant expression of integral or unscoped enumeration type.
The preceding (quite lengthy) paragraphs describe the rules for core constant expressions, but basically in C++11 the double initializer does not prevent i
being a core constant expression, even without a cast, so it is an integral constant expression and therefore a valid array bound, so no warning.
这篇关于用浮点文本初始化const int的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!