ayu*_*hen 5 c c++ comparison unsigned signed
"直觉"我指的是
int a = -1;
unsigned int b = 3;
Run Code Online (Sandbox Code Playgroud)
表达式(a < b)应该评估为1.
Stackoverflow上有很多问题已经问到为什么在这个或那个特殊情况下C编译器会抱怨签名/无符号比较.答案归结为整数转换规则等.然而,在比较烧结和无符号整数时,为什么编译器必须如此格外愚蠢似乎没有理由呢?使用上面的声明,为什么表达式喜欢
(a < b)
Run Code Online (Sandbox Code Playgroud)
不会自动替换
(a < 0 || (unsigned int)a < b)
Run Code Online (Sandbox Code Playgroud)
如果没有单机指令正确执行?
现在,对于以前的问题已经有了一些评论,"如果你必须混合有符号和无符号整数,那么你的程序就有问题".我不会买,因为libc本身使得无法生活在仅有符号或无符号的世界中(例如sprintf(),函数系列函数返回int为写入的字节数,send()返回ssize_t等).
我也不认为我可以购买下面评论中表达的一个想法,即将有符号整数隐式转换为无符号((d - '0' < 10U)"成语")赋予C程序员一些额外的权力,而不是显式的 cast(((unsigned int)(d - '0') < 10U)).但可以肯定的是,它打开了大量机会搞砸了.
是的,我很高兴编译器警告我它不能这样做(不幸的是只有我明确地问它).问题是 - 为什么不能呢?通常标准规则背后有很好的理由,所以我想知道这里有没有?
无法进行自动替换,因为它与C语义不同,并且会严重破坏正确使用转换的程序.例如:
if (d-'0'<10U) // false if d is not a digit
Run Code Online (Sandbox Code Playgroud)
对于ASCII空间和许多其他字符,您的建议替换将成为现实.
顺便说一句,我认为这个问题部分与以下问题重复:
如果我们在C/C++中添加安全签名/无符号比较,它会破坏语言或现有代码吗?
如果我没记错的话,这只是一个警告,因此可以忽略。
问题是整数变体的范围。
有符号整数可以保存从 -2147483648 到 2147483648(+- 1 或 2)的值,而无符号整数的范围可以从 0 到 4294967296。
这意味着,如果将有符号整数与无符号整数进行比较,可能会导致完全错误的结果,因为符号在内部由整数的 MSB 表示。
一个例子:
您有数字 -1 和数字 3,000,000,000。哪一个更大?显然,您可能会说第二个......但对于计算机来说,-1 实际上更大,因为“作为无符号”(正确评估大数字是必需的),-1 表示为最大数字。(4294967296)。
相反,如果两者都被视为有符号,那么大数将是一些相当大的负数,因为它超出了有符号整数的范围。
这就是编译器输出此警告的原因。虽然实际的错误情况相当罕见,但仍有可能发生。这正是编译器警告您的......在比较两个不同符号的整数时可能会发生意外的情况。