如何在C中输入一个文字

时间:2009-09-01 13:13:35

标签: gcc casting literals gcc-warning

我有一个小样本函数:

#define VALUE 0

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

我的编译器警告我,比较(x> = VALUE)在所有情况下都是正确的,这是正确的,因为x是无符号字符,VALUE定义为值0.所以我将代码更改为:

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

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

在更改的情况下,我有这个显式的强制转换,它应该是一个有符号的int比较。为什么声称这种比较总是正确的呢?

4 个答案:

答案 0 :(得分:12)

即使使用强制转换,在所有已定义行为的情况下仍然可以进行比较。编译器仍然确定(signed int)0的值为0,并且如果您的程序已定义行为,仍然确定(signed int)x)是非负的(如果值超出范围,则从unsigned转换为signed是未定义的签名类型)。

因此,编译器会继续发出警告,因为它会继续完全消除其他情况。

修改:要使警告静音,请将代码编写为

#define VALUE 0

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

答案 1 :(得分:7)

xunsigned char,这意味着它介于0到256之间。由于int大于char,因此将unsigned char转换为{{} 1}}仍保留signed int的原始值。由于此值始终>> = 0,因此char始终为真。

答案 2 :(得分:3)

unsigned char的所有值都可以在int中完美展现,因此即使使用演员,你也永远不会得到负值。您需要的投射是signed char - 但是,在这种情况下,您应该在函数签名中将x声明为signed。没有必要向客户说明你需要一个无符号值,而实际上你需要一个签名值。

答案 3 :(得分:1)

#define VALUE0表示您的功能已降至此:

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

由于x始终作为unsigned char传递,因此无论您是否{{1},它都将始终具有0255之间的值。 {}}或x0语句中的signed int。因此,编译器警告您if将始终大于或等于x,并且永远不会达到0子句。