首先,我想指出的是,我确实读过其他一些标题大致相似的答案。然而,这些建议要么指的是我认为是较旧版本的标准,要么涉及晋升,而不是转换。
我一直在学习"C++速成班“,在本章中,作者在探索内置操作符一章中说明了以下内容:
如果浮点提升规则都不适用,则检查其中一个参数是否已签名。如果是,则两个操作数都将被签名。最后,与浮点类型的提升规则一样,最大操作数的大小用于提升其他操作数:.
如果我正确地阅读了标准,这是不正确的,因为,根据cppreference.com,
如果两个操作数都有符号或两者都是无符号的,则转换级别较小的操作数转换为具有较大整数转换秩的操作数。
否则,如果无符号操作数的转换秩大于或等于符号操作数的转换秩,则符号操作数被转换为无符号操作数的类型。
否则,如果符号操作数的类型可以表示无符号操作数的所有值,则未签名操作数转换为有符号操作数的类型。
否则,两个操作数都转换为符号操作数类型的无符号对应项。
更让我困惑的是,以下代码:
printf("Size of int is %d bytes\n", sizeof(int));
printf("Size of short is %d bytes\n", sizeof(short));
printf("Size of long is %d bytes\n", sizeof(long));
printf("Size of long long is %d bytes\n", sizeof(long long));
unsigned int x = 4000000000;
signed int y = -1;
signed long z = x + y;
printf("x + y = %ld\n", z);产生以下输出:
Size of int is 4 bytes
Size of short is 2 bytes
Size of long is 8 bytes
Size of long long is 8 bytes
x + y = 3999999999就我所理解的标准而言,y应该被转换为unsigned int,从而导致不正确的结果。结果是正确的,这导致我假设在这种情况下没有发生转换。为什么?如果在这件事上有任何分歧,我将不胜感激。谢谢。
(我也很感激有人告诉我,在现实生活中,我永远不需要这种神秘的知识,即使这不是真的--只是为了内心的平静。)
发布于 2020-02-14 12:51:02
负号值到无符号值的转换将引向对应于它的二进制补码值。此无符号值的添加将导致溢出,其结果与添加负值所产生的值完全相同。
顺便问一句:这就是处理器如何进行减法的诀窍(或者说,在这些现代时代,我错了吗?)
发布于 2020-02-14 13:09:39
如果我正确地阅读了标准,这是不正确的
你说得对。CCC是错的。
,据我所知,y应该被转换成无符号int,
确实是这样。
结果是正确的,这导致我假设在这种情况下没有发生转换。
你假设错了。
由于-1不是可表示的无符号数字,它只是将可表示的数字转换为可表示的数字,并且与-1模可表示值的数目一致。当您将它添加到x中时,结果比任何可表示的值都要大,因此结果也是与模块一致的可表示值。由于模块运算的神奇之处,你得到了正确的结果。
发布于 2020-02-14 13:06:37
您有一个无符号int和有符号int的加法,因此这两个操作数的转换级别相同。因此,第二条规则将适用(强调我的):
否则,如果无符号操作数的转换秩大于或等于与符号操作数的转换秩相等,则符号操作数转换为无符号操作数的类型。
将complement)
标准授权转换为无符号类型,因为无符号溢出是由标准定义的,而无符号溢出则不是。
https://stackoverflow.com/questions/60226543
复制相似问题