我有一个小样本函数:

#define VALUE 0

int test(unsigned char x) {
  if (x>=VALUE)
    return 0;
  else
    return 1;
}

我的编译器警告我说的比较(X> = VALUE)是在所有情况下,这是正确的真实的,因为x是一个无符号的字符和值与值0,所以我改变代码来定义:

if ( ((signed int) x ) >= ((signed int) VALUE ))

但警告再来。我有三个版本的GCC(所有版本> 4.0,有时你必须启用-Wextra)。

测试了它

在改变的情况下,我有这样的明确的转换,它应该是一个符号的int比较。为什么声称,该比较始终是真的吗?

有帮助吗?

解决方案

即使铸造,比较仍处于定义的行为的所有的情况下如此。编译器仍然确定(signed int)0具有值0,并且仍然确定(signed int)x)是非负的,如果你的程序已定义的行为(从无符号铸造到签署如果值超出了范围为有符号的类型是未定义的)。

因此,编译器将继续警告,因为它继续完全消除别的情况。

修改:要消除警告,写你的代码

#define VALUE 0

int test(unsigned char x) {
#if VALUE==0
  return 1;
#else
  return x>=VALUE;
#endif
}

其他提示

xunsigned char,这意味着它是0到256之间,并由于一个intchar更大,铸造unsigned charsigned int仍保留chars原始值。由于该值总是> = 0,您的if是总是如此。

这是unsigned char的所有值可以在int完美杉,所以即使有投你永远不会得到一个负值。你需要演员阵容是signed char - 然而,在这种情况下,你应该申报x在函数签名signed。没有一点卧而实际上你需要签署一个,你需要一个无符号价值的客户。

#defineVALUE0意味着您的功能被减少到这样的:

int test(unsigned char x) {
  if (x>=0)
    return 0;
  else
    return 1;
}

由于x总是传递作为unsigned char,那么它将永远有0255之间的值,无论您在x陈述投0signed intif。因此,编译器警告您x永远是大于或等于0,那else条款不能达成。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top