我有一个"C"代码片段
如下int32_t A = 5;
uint32_t B = 8;
if ( A >= B )
{
printf("Test");
}
当我构建它时,我收到了一个评论/警告,作为"有符号和无符号操作数之间的比较。任何人都可以解决这个问题吗?
一切都很好,而A
是积极的,B
小于2^31
。
但是,如果A
小于0
,则会发生意外行为。
A = -1
,在内存中将保存为0xFFFFFFFF
。B = 5
,在内存中将保存为0x00000005
。
当你这样做时
if (A < B) {
//Something, you are expecting to be here
}
编译器会将它们作为无符号 32 位整数进行比较,您的 if 将扩展到:
if (0xFFFFFFFF < 0x00000005) {
//Do something, it will fail.
}
编译器会警告您此可能的问题。
对无符号整数和有符号整数的比较操作
很好,非常好!您正在阅读并注意编译器警告。
在您的代码中:
int32_t A = 5;
uint32_t B = 8;
if ( A >= B )
{
printf("Test");
}
您'A'
为最小值/最大值为-2147483648/2147483647
的有符号int32_t
值,以及最小值/最大值为0/4294967295
的无符号uint32_t
。编译器生成警告,以防止根据所涉及的类型始终为真或假的情况。在这里,对于允许的B
范围内的任何值,A
永远不能大于2147483648 - 4294967295
的B
。无论涉及的单个值如何,整个数字都将提供False
。
另一个很好的例子是if ( A < B )
它为来自-2147483648 - -1
的所有A
值生成一个TRUE
,因为无符号类型永远不能小于零。
编译器警告是为了警告使用这些类型的测试可能无法为某些数字范围提供有效的比较 - 您可能没有预料到。
在现实世界中,如果你知道A
只保存来自0 - 900
的值,那么你可以简单地告诉编译器1(你理解警告,并且通过你的强制转换将2(保证这些值将提供有效的测试,例如
int32_t A = 5;
uint32_t B = 8;
if (A >= 0 ) {
if ( (uint32_t)A >= B )
printf("Test");
}
else
/* handle error */
如果你不能保证1(和2(,那么是时候以一种你不会面对警告的方式重写代码了。
这里发生了两件好事。您启用了编译器警告,并且花时间阅读并理解编译器告诉您的内容。这将一次又一次地出现。现在您知道如何确定可以/应该做什么。