”在不同类型间提升操作数的相对简单的处理规则“在ANSI/ISO C中有了一些轻微的改变
举个例子:
ERROR : ”semantics of ’ >’ change in ANSI C
意思是错误,语法变化存在于ANSI C。
上面指出了有些代码在ANSI C的“值保护”规则下得到的结果可能跟老的“无符号保护”规则下得到的结果不同。这条警告事实上指出的是:当两个不同的类型出现在二元操作符的两侧或者对短的整数类型进行提升时,总是发生的隐式类型转换语义。
在ANSI/ISO C的保护规则下,若涉及无符号规则提升到“大”类型时的行为,一般存在两种保护规则:无符号保护、值保护
二者区别
无符号保护规则:提升的类型总是无符号的。
值保护规则:如果提升的类型足够大,即提升后的有符号类型能够表示的了无符号类型,则用有符号类型表示提升前的无符号类型。若提升的类型和之前的无符号类型一样大,则和无符号保护规则一致。
举个例子:
代码片段:
#include<stdio.h>
int main()
{
unsigned short int a=10;
int b=-5;
if(b>a)
printf("无符号保护规则\n");
else printf("值保护规则\n");
printf("int %d-----unsigned short int %d",sizeof(int),sizeof(unsigned short int));
return 0;
}
在上述代码中,a是unsigned short int型,但在和b进行比较的时候a会提升位为int型,与真实值10保持一致。
这里的int和unsigned short int 类型大小不一致,故编译器选择了值保护规则,事实上ANSI/ISO C标准也是采用了值保护规则的。。。
再看一例
代码片段:
#include<stdio.h>
int main()
{
unsigned char a=0x80;
unsigned long b=0;
b|=a<<8;
printf("0x%lx\n",b);
printf("unsigned int %d-----unsigned long %d",sizeof(unsigned int),sizeof(unsigned long));
return 0;
}
如果是在无符号保护的规则下(a被提升为unsigned int,unsigned int 和unsigned long 一样 大)则会打印出0x8000。但在值保护规则下,a会被提升为int 型,然后a<<8的结果也会被提升为long型,如果long型大于int型,则a<<8的结果会带符号进行提升,则打印结果为0xffff8000,但是如果long型和int型大小一致则值保护规则和无符号保护规则相一致。因为此编译器的int 和long大小一致,故打印0x8000
总结
针对以上这个保护规则问题,最好的解决办法就是不要让它发生,一旦发生那么势必会降低程序的可移植性,所以我建议在代码中 最好避免在同一个表达式中混用有符号和无符号变量