用浮点文本初始化const int [英] Initializing a const int with a floating point literal

查看:161
本文介绍了用浮点文本初始化const int的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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, and sizeof 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆