繁体   English   中英

类型转换为不同的编译器提供不同的结果

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM