类型转换的一个问题

vv1133 2010-02-09 04:42:09
#include<stdio.h>

#define IS(a) (a>=0 && ~a>=0)

int main()
{
int c = 4;
unsigned int b = 5;
char d = 6;
unsigned char e = 7;
printf("int=%d\n",IS(c));
printf("uint=%d\n",IS(b));
printf("char=%d\n",IS(d));
printf("uchar=%d\n",IS(e));//这句有警告
}

宏的意思是判断这个变量是signed型的还是unsinged型的

编译出现警告:
sign_test.c: In function `main':
sign_test.c:14: warning: comparison is always true due to limited range of data
type
请问这是什么原因,怎么解决啊?
...全文
227 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
vv1133 2010-02-13
  • 打赏
  • 举报
回复
- 谢谢
bladesoft 2010-02-11
  • 打赏
  • 举报
回复
楼主还没有理解。
我再解释一下,一条一条列出来。

unsigned char和0比较晋升为signed int,这里由于编译器优化的缘故,认为unsigned char >=0,所以给出了报警;
signed char和0比较晋升为signed int(之前我说char没有晋升是不对的,后来又查了资料),因为它是有符号数,编译器不知道他是否大于等于0,因为它也有可能小于0,所以这个没有警告;
unsigned int和0比较,一边有符号一边没有符号,而且两边rank一样,这里把0转化为unsigned int,然后两者再进行比较,编译器不能进行优化,因为和第一条情况不一样,所以也没有警告;
signed int和0比较,两边符号和Rank一样,这个就不用解释了吧。

关于rank,这个多看看类型转换的规则,自然就明白。


楼主说大家的回答都不能让你满意,我笑而不语。
bladesoft 2010-02-11
  • 打赏
  • 举报
回复
unsigned int不存在位数上的晋升。你看到的这个警告主要是针对要比较大小,晋升了数据类型,晋升后编译器认为没有必要和0进行比较这种情况产生的。
自己在多体会体会吧
vv1133 2010-02-11
  • 打赏
  • 举报
回复
那为啥unsigned int就没警告了?

我发现大家的回答都不能让我满意
引用 11 楼 zhao4zhong1 的回复:
unsigned char 的取值范围是0~255,当然永远≥0了。所以编译器警告你是应该的。
赵4老师 2010-02-10
  • 打赏
  • 举报
回复
unsigned char 的取值范围是0~255,当然永远≥0了。所以编译器警告你是应该的。
forster 2010-02-10
  • 打赏
  • 举报
回复
if(2 > 1)警告。。
bladesoft 2010-02-10
  • 打赏
  • 举报
回复
前一行的char是有符号的,是可以和0进行比较的,它不用晋升的,所以它不会有问题
vv1133 2010-02-09
  • 打赏
  • 举报
回复
但是前一行的char转成int也一样,为什么就没有警告?
引用 9 楼 bladesoft 的回复:
引用楼主 vv1133 的回复:C/C++ code#include<stdio.h> #define IS(a) (a>=0&&~a>=0)int main() {int c=4; unsignedint b=5;char d=6; unsignedchar e=7; printf("int=%d\n",IS(c)); printf("uint=%d\n",IS(b)); printf("char=%d\n",IS(d)); printf("uchar=%d\n",IS(e));//这句有警告} 宏的意思是判断这个变量是signed型的还是unsinged型的 编译出现警告: sign_test.c: In function `main': sign_test.c:14: warning: comparison is always true due to limited range of data type 请问这是什么原因,怎么解决啊?
当unsigned char和0比较大小时,unsigned char类型晋升为int,由于char长度小于int类型长度,因此转换为int后,该变量最高位肯定为0,所以这个变量必然大于等于零,so......
bladesoft 2010-02-09
  • 打赏
  • 举报
回复
引用楼主 vv1133 的回复:
C/C++ code#include<stdio.h>

#define IS(a) (a>=0&&~a>=0)int main()
{int c=4;
unsignedint b=5;char d=6;
unsignedchar e=7;
printf("int=%d\n",IS(c));
printf("uint=%d\n",IS(b));
printf("char=%d\n",IS(d));
printf("uchar=%d\n",IS(e));//这句有警告}
宏的意思是判断这个变量是signed型的还是unsinged型的

编译出现警告:
sign_test.c: In function `main':
sign_test.c:14: warning: comparison is always true due to limited range of data
type
请问这是什么原因,怎么解决啊?

当unsigned char和0比较大小时,unsigned char类型晋升为int,由于char长度小于int类型长度,因此转换为int后,该变量最高位肯定为0,所以这个变量必然大于等于零,so......
vv1133 2010-02-09
  • 打赏
  • 举报
回复
引用 2 楼 traceless 的回复:
类型提升啊

默认类型是int,你想要的

printf("uchar=%d\n",IS((unsigned int)e));//这句有警告

谢谢,但 程序的目的是判断变量是有符号的还是无符号的,强制转成unsigned int就没意义了
traceless 2010-02-09
  • 打赏
  • 举报
回复
宏管啊

#define 5 //int型
#define 5L //long型

那样来做没意义

要有意义的话得这样:

引用 1 楼 taodm 的回复:
倒!看没看见呗。
一般,这是C++模板元编程干的活。
jack_wq 2010-02-09
  • 打赏
  • 举报
回复
引用 5 楼 cy330206 的回复:
引用 2 楼 traceless 的回复:
类型提升啊

默认类型是int,你想要的

printf("uchar=%d\n",IS((unsigned int)e));//这句有警告
一般宏不是不管类型的嘛

宏只是替换吧
cy330206 2010-02-09
  • 打赏
  • 举报
回复
引用 2 楼 traceless 的回复:
类型提升啊

默认类型是int,你想要的

printf("uchar=%d\n",IS((unsigned int)e));//这句有警告

一般宏不是不管类型的嘛
pang123hui 2010-02-09
  • 打赏
  • 举报
回复
引用 3 楼 freezezdj 的回复:
我从来不管警告信息。


最好是0错误,0警告,这样才和谐哦
冻结 2010-02-09
  • 打赏
  • 举报
回复
我从来不管警告信息。
traceless 2010-02-09
  • 打赏
  • 举报
回复
类型提升啊

默认类型是int,你想要的

printf("uchar=%d\n",IS((unsigned int)e));//这句有警告



taodm 2010-02-09
  • 打赏
  • 举报
回复
倒!看没看见呗。
一般,这是C++模板元编程干的活。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧