比较8位不同符号类型(int8_t, uint8_t):是结果确定性的
Comparing 8 bits types of different signedness (int8_t, uint8_t): is result deterministic?
我运行这个简单的程序:
#include <stdint.h>
#include <iostream>
int main() {
uint8_t x = 100;
int8_t y = -128;
if (x < y) {
std::cout << (int) x << " is less than " << (int) y << std::endl;
} else {
std::cout << (int) y << " is less than " << (int) x << std::endl;
}
}
正确输出:
-128 is less than 100
一开始我很惊讶地发现没有生成签名警告。
然后我很惊讶没有错误的转换正在进行(-128 -> 255),因此没有得到错误的结果。
然后我读到这个:
1除bool、char16_t、char32_t或wchar_t以外的整型右值,如果整型能表示源类型的所有值,则可将其转换为整型右值,其整型转换等级(4.13)小于int;否则,源右值可以转换为unsigned int类型的右值。(§4.5)
链接到标准n2356
"可以转换"是什么意思?它是由编译器实现,如果这种转换将发生,因此,如果这个表达式将返回一个正确的值?
注意:我还标记了C,因为这种情况似乎也适用于它。
相关问题:有符号和无符号字符的比较。也这样。
是的,结果是确定的,而不是(编译器的)实现定义的。这里遵循c++ 11的动机(应该可以为其他版本做同样的事情),遵循此处的文档(此处建议链接)
有必要将以下所有内容结合起来:
5.9关系运算符
[…]
通常的算术转换在算术或枚举类型的操作数上执行。
要找到常用的算术转换,我们需要翻到第5章第9段的开头:
许多要求操作数为算术或枚举类型的二元操作符会导致转换并产生结果结果以类似的方式类型。目的是产生一个公共类型,这也是结果的类型。此模式称为常规算术转换,定义如下:
- […(枚举和浮点类型)
否则,积分提升(4.5)将同时在操作数[59]。那么以下规则将适用于提升的操作数:
- 如果两个操作数的类型相同,则不需要进一步的转换。
- […]
所以,积分提升,引用4.5:
非 bool、char16_t、char32_t或wchar_t的整型右值如果int可以表示所有,则可以将其转换为int类型的右值源类型的值;否则,源右值可以转换为unsigned类型的右值int。
:
我们有一个关系运算符,将使用通常的算术转换。这些要求应用积分提升。uint8_t
和int8_t
对int
的积分提升是可能的,因此必须采用。
因此,编译器将一个uint8_t
与int8_t
的比较转换为两个int
的比较。不存在不确定性行为
这里有一个类似的Q/a(关于short
类型),它引导我走向正确的道路。
注意以下矛盾:关系操作符返回布尔值(5.9.1),但它们使用通常的算术转换,用于获得相同类型的两个操作数。但是,问题就在这里,通常的算术转换的定义说,公共类型也是结果的类型,这与关系操作符的情况不同!
对于C11不存在矛盾,关系操作符返回的结果确实是一个int
。(感谢chux)
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 使用++运算符会导致意外的结果
- 从值小于256的uint16到uint8的Endian安全转换
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 算术运算的结果类似于:C浮点变量中的1/3
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 密码登录程序将永远循环并显示不正确的结果
- 如何让C++'tally up'结果并制定计划?
- 为什么这个程序的结果是3 "born"?和 4 死