且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么不缩小转换使用与大括号分隔的初始化程序导致错误?

更新时间:2021-10-23 20:48:37

这是错误的,应该有诊断,作为警告(您收到的 )或错误。 gcc因为从C ++ 03移植问题而导致几个版本的警告

This is ill-formed and there should be diagnostic, however it can either be a warning(which you received) or an error. gcc made this a warning for several versions due to porting issue from C++03:


标准只要求一致的实施应至少发出一个诊断消息警告。如安德鲁所说,-Werror = narrowing允许你使它成为一个错误,如果你想要的。

The standard only requires that "a conforming implementation shall issue at least one diagnostic message" so compiling the program with a warning is allowed. As Andrew said, -Werror=narrowing allows you to make it an error if you want.

G ++ 4.6给出一个错误,但它被改为一个警告故意为4.7,许多人(包括我自己)发现,缩小转换,其中最常遇到的问题之一,当试图编译大型C ++ 03代码库作为C ++ 11。以前格式良好的代码,如char c [] = {i,0}; (我只会在char的范围内)引起的错误,必须更改为char c [] = {(char)i,0}

G++ 4.6 gave an error but it was changed to a warning intentionally for 4.7 because many people (myself included) found that narrowing conversions where one of the most commonly encountered problems when trying to compile large C++03 codebases as C++11. Previously well-formed code such as char c[] = { i, 0 }; (where i will only ever be within the range of char) caused errors and had to be changed to char c[] = { (char)i, 0 }

,但现在最近的gcc和clang版本使此为错误,查看它的gcc

but now recent versions of gcc and clang make this an error, see it live for gcc.

参考 draft C ++ 11标准部分 8.5.4 [dcl.init.list] / em>说:

For reference the draft C++11 standard section 8.5.4 [dcl.init.list] says:


否则,如果初始化器列表有一个元素,对象或
引用从元件;如果需要缩小转换
(见下文)将元素转换为T,程序是
格式不正确。 [示例:

Otherwise, if the initializer list has a single element, the object or reference is initialized from that element; if a narrowing conversion (see below) is required to convert the element to T, the program is ill-formed. [ Example:

int x1 {2}; // OK
int x2 {2.0}; // error: narrowing

-end示例]

和:


缩小转换是隐式转换

A narrowing conversion is an implicit conversion


  • 从浮点类型转换为整数类型,或

...]

[注意:如上所述,列表初始化中不允许在顶层进行此类转换。-end
note] :

[ Note: As indicated above, such conversions are not allowed at the top level in list-initializations.—end note ] [ Example:

[...]

int ii = {2.0}; // error: narrows

[...]

因此,浮点数到整数转换是一个缩小的转换,并且是错误的。

So a floating point to integer conversion is a narrowing conversion and is ill-formed.

1.4 实施合规性[intro.compliance]说:

and section 1.4 Implementation compliance [intro.compliance] says:


虽然本国际标准仅声明对C ++实现,那些需求
通常更容易理解,如果他们被称为程序,部分程序或
执行程序的要求。此类要求具有以下含义:

Although this International Standard states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:

[...]


  • 程序包含违反任何可诊断规则或本标准中的
    描述为有条件支持的结构,当实现不支持该结构时,
    a符合实现应发出至少一个诊断

[...]

告诉我们只需要诊断。