简体   繁体   English

为什么“ unsigned int ui = {-1};”会缩小转换错误?

[英]Why is “unsigned int ui = {-1};” a narrowing conversion error?

The Standard at § 8.5.4/7 explains what a narrowing conversion is: §8.5.4 / 7中的标准解释了缩小的转换是:

A narrowing conversion is an implicit conversion 缩小转换是隐式转换

— from a floating-point type to an integer type, or —从浮点类型到整数类型,或者

— from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or —从long double到double或float,或者从double到float,除非源是一个常量表达式,并且转换后的实际值在可以表示的值范围内(即使不能精确表示),或者

— from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or —从整数类型或无作用域枚举类型到浮点类型,除非源是常量表达式,并且转换后的实际值将适合目标类型,并在转换回原始类型时将产生原始值,要么

— from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type. —从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型,除非源是常量表达式,并且转换后的实际值将适合目标类型并产生原始值当转换回原始类型时。

It then disallows such conversions in some list-initialization contexts, giving examples: 然后,它在某些列表初始化上下文中禁止进行此类转换,并提供示例:

[ Note: As indicated above, such conversions are not allowed at the top level in list-initializations. [注意:如上所述,在列表初始化中,不允许在顶层进行此类转换。 — end note ] [ Example: —尾注] [示例:

int x = 999;        // x is not a constant expression
const int y = 999;
const int z = 99;
char c1 = x;    // OK, though it might narrow (in this case, it does narrow)
char c2{x};     // error: might narrow
char c3{y};     // error: narrows (assuming char is 8 bits)
char c4{z};     // OK: no narrowing needed
unsigned char uc1 = {5};    // OK: no narrowing needed
unsigned char uc2 = {-1};   // error: narrows
unsigned int ui1 = {-1};    // error: narrows
signed int si1 =
{ (unsigned int)-1 };   // error: narrows
int ii = {2.0};         // error: narrows
float f1 { x };         // error: might narrow
float f2 { 7 };         // OK: 7 can be exactly represented as a float
int f(int);
int a[] =
{ 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level

— end example ] —结束示例]

All 7 of the errors illustrated by the examples are reported as such by clang 3.2/3.3 with -std=c++11 , eg 示例所说明的所有7个错误都是由clang 3.2 / 3.3报告,带有-std=c++11 ,例如

error: non-constant-expression cannot be narrowed from type 'int' to 'char' in initializer list [-Wc++11-narrowing]

None of them are reported as errors by gcc 4.7.2/4.8.1, but in each case a similar warning is given, eg gcc 4.7.2 / 4.8.1均未将它们报告为错误,但是在每种情况下都给出类似的警告,例如

warning: narrowing conversion of ‘x’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]

(so gcc seems to know what compliance requires but opts to tolerate non-compliance by default.) (因此,gcc似乎知道合规性要求,但默认情况下选择容忍不合规。)

What I do not understand is how the example: 我不明白的是这个例子:

unsigned int ui1 = {-1};    // error: narrows

qualifies as an example. 有资格作为一个例子。 (Likewise with the symmetrical si1 example.) Evidently the only words by which it might qualify as example are those of the fourth and final item in the definition of narrowing conversion given above; (同样地与对称si1示例)。显然,通过该它可能有资格作为示例的唯一字是那些在上面给出的缩小转换的定义中的第四和最后一个项目的; but if so then why does the example not escape by the qualification except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type ? 但是,如果是这样,那么为什么示例不能通过限定条件进行转义, 除非源是一个常量表达式,并且转换后的实际值将适合目标类型,并在转换回原始类型时会产生原始值 Surely -1 there is an integer constant and, if converted to unsigned and back, still yields int -1 ? 当然-1有一个整数常数,如果将其转换为unsigned并返回,则仍会得出int -1

What am I missing? 我想念什么?

Surely -1 there is an integer constant and, if converted to unsigned and back, still yields int -1? 当然-1有一个整数常量,如果将其转换为无符号并返回,则仍会得出int -1?

This is wrong. 错了 If you convert -1 to unsigned you get UINT_MAX . 如果将-1转换为unsigned则会得到UINT_MAX This is fine because converting to unsigned types is always defined. 这很好,因为始终定义为转换为无符号类型。 However, UINT_MAX does not fit in int and conversions to signed types are only defined by the standard when the value fits in the target type. 但是, UINT_MAX不适合int ,只有当值适合目标类型时,才由标准定义对有符号类型的转换。

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

相关问题 将unsigned int转换为short unsigned int - Narrowing Conversion of unsigned int to short unsigned int 缩小从 int 到 unsigned char 的转换 - Narrowing conversion from int to unsigned char 错误 C2397:从“int”到“unsigned int”的转换需要缩小转换 - error C2397: conversion from 'int' to 'unsigned int' requires a narrowing conversion 从“unsigned int”到“int”的转换需要缩小转换 - conversion from 'unsigned int' to 'int' requires a narrowing conversion 错误:'18446744069414584320ull'从'long long unsigned int'到'int'的缩小转换{} [-Wnarrowing] - error: narrowing conversion of ‘18446744069414584320ull’ from ‘long long unsigned int’ to ‘int’ inside { } [-Wnarrowing] C ++-从“ int”到“ unsigned char”的无效缩小转换 - C++ - Invalid narrowing conversion from “int” to “unsigned char” 从 (int) 到 (short) 错误的无效缩小转换 - invalid narrowing conversion from (int) to (short) error 从无符号转换为双精度 - narrowing conversion from unsigned to double 为什么此代码中没有缩小转换,导致错误? - Why is there no narrowing conversion in this code, resulting in an error? 缩小从int到long unsigned int {}的转换在C ++ 11中是不正确的 - narrowing conversion from int to long unsigned int {} is ill-formed in C++11
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM