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

时间:2014-05-19 04:40:31

标签: c casting

这只是一个基本的东西,但仍然与此混淆

我的代码由一行

组成
signed char var = 0x80;
unsigned short temp_val;
temp_val = (unsigned short)var ;

当我使用 XC32 编译器编译此代码并执行该程序时,获得的结果是 0xFF80 ,如预期的那样。

但是当使用 CCS编译器编译 MSP430 时,获得的结果是 0x0080

为什么这与编译器有区别?

有人可以从处理器的类型转换视图中解释这个吗?

3 个答案:

答案 0 :(得分:1)

这是带符号的整数溢出,因为0x80等于128,如果CHAR_BIT为8,那么signed char最多只能达到127。

signed char var = 0x80;

有符号整数溢出会产生未定义的行为。

尝试使用signed char var = -128

如果产生相同的结果,则是编译器错误。将负数转换为unsigned类型会从相应的模数中减去它,该模数比该类型的最大值大1。

答案 1 :(得分:0)

如果char超过8位,那肯定会发生这种情况。 (它可能没有更少。)如果short仅为8位,这也不会符合标准C,但CCS编译器只声称是&# 34; 97%"兼容。

各种整数数据类型的大小由处理器决定,但最终由编译器定义,编译器甚至可以选择更改大小。

我对MSP430一无所知,但谷歌告诉我它是一个16位芯片。它的存储器可能不是字节可寻址的,在这种情况下,char必须占用整个16位。 (编辑:显然,它是字节可寻址的,所以刮开那个理论。)

答案 2 :(得分:0)

任何字符都可以是到编译器,各种长度取决于编译器设置,包括7位(这些天很少见),8位(大多数人认为是什么)它是,16位(尤其是使用Unicode更常见),我甚至遇到了机器/编译器组合,它们将存储 64位的每个字符串。

编译器之间的这种差异是MISRA C制定规则的原因:

  • 基本类型
  • 签名类型的位操作

仅仅因为芯片是字节可寻址的,并不意味着任何给定的编译器都会以这种方式使用 默认 ,因为16和更大的存储系统上的字节操作可能会导致处理开销一些编译器默认使用内存大小操作来优化速度而不是存储。

我建议在编译器文档中搜索 pack

几年前,默认的Solaris编译器在位字段中为每个字段使用了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;

这可能会突出显示编译器中符号扩展的问题。