[英]Type casting gives different results for different compilers
这只是一个基本的东西,但仍然与此混淆
我的代码由一行组成
signed char var = 0x80;
unsigned short temp_val;
temp_val = (unsigned short)var ;
当我使用XC32编译器编译此代码并执行程序时,所获得的结果为0xFF80,如预期的那样。
但是,使用CCS编译器针对MSP430进行编译时 ,获得的结果为0x0080
为什么在编译器方面存在这种差异?
有人可以从处理程序的类型转换角度来解释这一点吗?
这是有符号整数溢出,因为0x80
等于128,并且,如您所说的,如果CHAR_BIT
为8,则有signed char
仅上升到127。
signed char var = 0x80;
有符号整数溢出会产生未定义的行为。
尝试使用带signed char var = -128
代替。
如果产生相同的结果,则是编译器错误。 将负数转换为unsigned
类型会从相应的模数中减去它,该模数比该类型的最大值大1。
如果char
具有8位以上的位,那肯定会发生。 (不能少。)如果short
最终只有8位,也不会发生,这不符合标准C,但是CCS编译器仅声称符合“ 97%”标准。
各种整数数据类型的大小由处理器确定,但最终由编译器定义,编译器甚至可以选择更改大小。
我对MSP430一无所知,但Google告诉我它是16位芯片。 它的内存可能不是字节寻址的,在这种情况下,一个char
必须占用全部16位。 ( 编辑 :显然,它是字节可寻址的,因此请从理论入手。)
对于编译器 ,任何字符都可以是不同的长度,具体取决于编译器设置,包括7位(如今很少见),8位(大多数人认为是),16位(在Unicode中越来越常见),我有甚至遇到了将每个字符存储在64位位置的机器/编译器组合。
编译器之间的这种差异是MISRA C制定针对以下规则的原因:
仅仅因为该芯片是字节可寻址的,并不意味着任何给定的编译器默认情况下都会以这种方式使用它,因为在16和更大存储系统上的字节操作可能会产生处理开销,因此某些编译器默认使用内存大小操作来优化速度而不是存储。
我建议在编译器文档中搜索pack 。
几年前,默认的Solaris编译器为bit字段中的每个字段使用了64位位置- 幸运的是,Solaris gcc并未这样做,因此我们能够完成该项目。
尝试也很有趣:
signed char var = 0x80;
signed short temp_val1;
unsigned short temp_val2;
temp_val1 = (signed short)var ;
temp_val2 = (unsigned short)temp_val1;
这可能会突出显示该编译器中符号扩展的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.