【发布时间】:2017-02-12 21:29:15
【问题描述】:
#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),因此没有得到错误的结果。
然后我读了this:
1 可以将除 bool、char16_t、char32_t 或 wchar_t 以外的整数类型的纯右值转换为整数转换等级 (4.13) 小于 int 等级的纯右值如果 int 可以表示源类型的所有值;否则,源纯右值可以转换为 unsigned int 类型的纯右值。 [§ 4.5]
Link to standard n2356
“可以转换”是什么意思?是否会发生这种转换并因此该表达式是否会返回正确的值是否取决于编译器实现?
重点是编译器应搜索将两个操作数转换为的通用类型,但我在标准中没有发现任何义务尽其所能 以便这种通用类型能够表示两种输入类型的所有可能值。
注意:我也标记了 C,因为这种情况似乎也适用于它。
相关问题:Comparison signed and unsigned char。还有this。
【问题讨论】:
-
在 C 中,
x,y在<之前都被转换为int(建议 1 个语言标签) -
@chux 当然可以,但是基于哪个规则?
-
@CoryKramer 积分提升的规则说“可能”,而不是“应该”。有什么我想念的吗?
-
C11 §6.3.1.1 2 "... 如果
int可以表示原始类型的所有值...,则将该值转换为int;否则,将其转换到unsigned int. ..." 如果代码使用uint16_t/int16_t,那么在 16 位和 32 位int平台上会出现差异。