一元 - 和n -

时间:2017-01-13 16:56:48

标签: c++ gcc unsigned-integer compiler-bug

我相当确定从另一个中减去一个uint8_t会产生另一个无符号数字,但我的一些结果让我感到困惑。

  uint8_t a = 2;
  uint8_t b = 1;
  uint8_t c = -a;
  long d = b - a;
  long e = b + c;

当我获得d的值时,它会生成-1,而e正如我所期望的那样255。这是我正在使用的gcc版本的错误.....对吧?

作为参考,我正在为arm-none-eabi-g++使用MSP-432编译器。

查看this似乎表明gcc似乎在这里犯了同样的错误。

this所以问题似乎是神杖和手臂gcc是错误的。

这里发生了什么?

2 个答案:

答案 0 :(得分:6)

  

这是我正在使用的gcc版本的错误.....对吗?

不,不是。在像gcc这样的大型编译器中出现错误的东西是非常不可能的。

发生的事情是由于"通常的算术转换",特别是"整数提升":

一元-a提升为int,然后(int)-2转换回作业中的uint8_t,产生c == 254(它是Z mod 2 ^ 8中等价类-2的代表,位于[0,2 ^ 8))。

同样,下面一行中的二进制文件+-会提升为int,因此我们最终会以

开头
d == (int)b - (int)a == (int)1 - (int)2 == -1

e == (int)b + (int)c == (int)1 + (int)254 == 255

所以一切都按标准要求正常工作。

答案 1 :(得分:2)

原因是二元运算符在完成工作之前会进行整体提升,并且由于int可以保存uint8_t中的所有可能值,因此使用该选项(请参阅http://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_promotion)。因此,减法是作为带符号的操作完成的。

在计算e时,c中存储值的行为已导致您的预期模数学运算,存储254,然后将其添加到b的值为1。