简体   繁体   English

使用浮点文字初始化const int

[英]Initializing a const int with a floating point literal

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). 使用g++ -O0 -Wall -pedantic -ansi -std=c++11编译上述代码不会产生任何错误(除了未使用的变量)。 However, if I remove -std=c++11 , I get the following warning: 但是,如果我删除-std=c++11 ,我会收到以下警告:

warning: ISO C++ forbids variable length array 警告:ISO C ++禁止可变长度数组

According to this SO question , I believe that in C++03, the code is invalid. 根据这个SO问题 ,我相信在C ++ 03中,代码无效。 However, can someone explain how the rule has changed in C++11? 但是,有人可以解释一下规则在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): 数组绑定必须是一个整型常量表达式,参见8.3.4 [dcl.array] / 1(C ++ 03和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. 如果存在常量表达式(5.19),则它应为整数常量表达式,其值应大于零。

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: 在C ++ 03中,除非转换为整数类型,否则不能通过浮动文字初始化整数常量表达式,请参见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, and sizeof expressions. 整数常量表达式只能包含文字(2.13),枚举器, const变量或使用常量表达式(8.5)初始化的整数或枚举类型的静态数据成员,整数或枚举类型的非类型模板参数以及sizeof表达式。 Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. 浮动文字(2.13.3)只有在转换为整数或枚举类型时才会出现。

This means that in C++03 i is not an integral constant expression, so cannot be used as an array bound. 这意味着在C ++ 03中i不是整数常量表达式,因此不能用作数组绑定。

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 . GCC和Clang允许可变长度数组作为C ++ 03的扩展,因此它使用非常量绑定进行编译,但是会出现-pedantic警告。 Changing the constant's initializer to cast it to integral type makes i a valid integral constant expression: 更改常量的初始值设定项以将其强制转换为整型,使得i成为有效的积分常量表达式:

const int i = (int) 1.0;

With that change the array is no longer variable length and there is no warning even with -pedantic . 通过该更改,数组不再是可变长度,即使使用-pedantic也没有警告。

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

A literal constant expression is a prvalue core constant expression of literal type, but not pointer type. 文字常量表达式是文字类型的prvalue核心常量表达式,但不是指针类型。 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. 前面(相当冗长的)段落描述了核心常量表达式的规则,但基本上在C ++ 11中,双重初始化器并不会阻止i成为核心常量表达式,即使没有强制转换,因此它是一个整型常量表达式,因此有效的数组绑定,所以没有警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM