C++ 缩小C+中的转换范围+;11:什么是";换算后的实际值;?

C++ 缩小C+中的转换范围+;11:什么是";换算后的实际值;?,c++,c++11,language-lawyer,C++,C++11,Language Lawyer,以下代码在C++11中合法吗 int16_t x {0xaabb}; int64_t xxxx {0xaaaabbbbccccdddd}; 来自《C++程序设计语言》第四版(第150页)。 正如我们所知,列表初始化不允许进行窄化转换,在标准对窄化转换的定义中,我们有: 缩小转换是一种隐式转换 -[…] -从整数类型或无范围枚举类型到不能表示原始类型的所有值的整数类型,除非源是常量表达式,并且转换后的实际值将适合目标类型,并在转换回原始类型时生成原始值 根据示例代码检查缩小转换规则,我证明示例代

以下代码在C++11中合法吗

int16_t x {0xaabb};
int64_t xxxx {0xaaaabbbbccccdddd};
<代码>来自《C++程序设计语言》第四版(第150页)。 正如我们所知,列表初始化不允许进行窄化转换,在标准对窄化转换的定义中,我们有:

缩小转换是一种隐式转换
-[…]
-从整数类型或无范围枚举类型到不能表示原始类型的所有值的整数类型,除非源是常量表达式,并且转换后的实际值将适合目标类型,并在转换回原始类型时生成原始值

根据示例代码检查缩小转换规则,我证明示例代码是非法的,因为
0xaabb
0xAAAABBBBCCDDDD
不能分别在
int16_t
int64_t
中表示。对吗

但我不太理解“除非源是一个常量表达式,并且转换后的实际值将适合目标类型,并且在转换回原始类型时将产生原始值”。我想知道在哪种情况下,转换后的实际值不能符合目标类型。由于整数类型之间的转换总是有效的(尽管在目标类型有符号且源值不能在目标类型中表示的情况下定义了实现,但无论如何这不是未定义的行为),因此“转换后的值将适合目标类型”是否总是正确的?从这个角度来看,我开始质疑我对示例代码缩小转换范围的判断。如果是这样的话,为什么标准在一个条件下总是把某些东西放在正确的位置?为什么不说“除非源是一个常量表达式,并且转换后的实际值在转换回原始类型时将产生原始值”


有人能帮我澄清一下吗?谢谢大家!

这是标准中的缺陷,请参阅。文本已更改为

从整数类型或无范围枚举类型到不能表示原始类型的所有值的整数类型,除非源是常量表达式,其值在整数提升后将适合目标类型


注意:问题的状态DRWP意味着官方标准尚未更改,可以提出一个论点,即至少您的
int64\t
示例在C++11中是合法的。不过,编译器已经实现了新规则,因为这已经是原始措辞的预期含义。

让我们看看如何将值转换为有符号整数:

4.7/3如果目的地类型是有符号的,如果可以在目的地类型(和位字段宽度)中表示,则该值不变;否则,该值由实现定义

因此,这些转换给出了实现定义的值。合理的实现将定义转换,为该位模式提供相应的负值,该位模式适合目标类型

所以问题是,转换回文本的类型会保留值吗?这取决于文字类型的实现定义的大小。如果
int
正好有16位,则第一个将保留该值,但如果大于16位,则不会保留该值(在这种情况下,
0xaabb
将被签名,并且转换将给出负值)。同样,如果
int
正好有64位,或者
int
较小,而
long
正好有64位,则第二个将保留该值


结论:视情况而定。在具有32位
int
和64位
long
的典型当前平台上,第一个平台将缩小,而第二个平台不会缩小。GCC同意,并对第一个问题发出警告,即
-pedantic

我认为问题来自这样一个事实,即
0xaabb
可以被视为一个“正”常量,但当分配给
int16_t
时,它会变成一个负数。嗯,我刚刚回复了一条已经不在这里的评论,但我会留下这条评论,因为它可能会澄清这个问题。你能改进标题,使它与问题列表中的其他问题区分开来吗?根据经验,它应该是合法的,因为GCC发出警告(因此编译器显然知道这个问题)但它不会发出错误。如果它真的是非法的,编译应该以一个错误(而不是警告)中断。@Damon:你的结论不正确。该标准不要求编译器在遇到非法代码时停止编译并出现错误。只需诊断错误,并发出警告即可。GCC的代码> >迂回错误>代码的目的是为了促进这种警告的错误。@达蒙在标准中没有这样的要求,而且GCC(就像其他编译器一样)只接受警告,在标准C++中不接受某些东西。非常感谢您的信息。我仍然不清楚“
将适合
”和“
可以在
中表示”之间的区别。如果它们的意思相同,那么
int64\t
示例应该是缩小转换范围。如果它们不一样,那么确切的区别是什么?@goodbyeera除非我误读,否则它们的意思是相同的,因此
int16\u t
int64\u t
示例都是基于新措辞的缩小转换。