在Mac上使用+ =时,静态uint8_t变量的值更改为不正确的值

时间:2019-04-22 15:56:39

标签: c static-variables

我今天有一个同事问我一个关于他的密码的问题,我无法回答。他正在Mac上编写一个C单元测试,该测试使用静态uint8_t变量(已初始化为0)来在测试代码中看似简单的读取函数的调用中保持来自测试缓冲区的当前读取位置。算法如下:

    /*Fails to add correctly on the third iteration of the loop \*/
    /* static uint8_t currentReadPosition = 0; \*/
    /* uint32_t tempreadamount \*/
    currentReadPosition += tempreadamount;

我在Linux上运行了代码,并且值正确更改(根据代码),因此问题似乎特定于Mac平台。我要求他事先将值从uint8_t更改为uint32_t,当他重新运行测试时,它可以正确运行。

    /* Works correctly \*/
    /* static uint32_t currentReadPosition \*/
    /* uint32_t tempreadamount \*/
    currentReadPosition += tempreadamount;

他在函数中使用了memcpy(),但是写入目的地不在函数的范围内(它将作为参数传递给read函数)。我没有发现使用错误的目标指针或其他任何问题。

我不知道为什么uint32_t可以工作而uint8_t在Mac上不能工作,但是uint8_t在Linux上可以正常工作。有人知道这是怎么回事吗?

谢谢。

uint8_t resetcurrptr = 0;
int readfunc_cb_test( uint8_t* OutBuf, uint32_t NumBytes )
{
static uint8_t currentReadPosition = 0;

  if( resetcurrptr )
  {
    currentReadPosition = 0;
  }

  uint32_t readamt = NumBytes;
  if( NumBytes > ( ( sizeof(TestRequestPacket) / sizeof(TestRequestPacket[0] ) ) - currentReadPosition) )
  {
    readamt = ( sizeof(TestRequestPacket) / sizeof(TestRequestPacket[0]) - currentReadPosition );
  }

  memcpy( OutBuf, &TestRequestPacket[currentReadPosition], readamt );

  currentReadPosition += readamt;

  return readamt;
}

2 个答案:

答案 0 :(得分:2)

所以,我今天早上解决了这个难题...

我的同事正在使用LLDB在Mac而不是GDB上进行调试。当他使用LLDB进行调试并且值达到8时,调试器将显示'\ b'。事实证明这不是0xB,而是'\ b'... BACKSPACE的ASCII码,其整数值为8。

只有当我们再次观察到他的结构时,我才发现了这个问题。(看起来)当它根本没有填充时,填充到11。

谢谢大家的回答。

答案 1 :(得分:1)

在uint8上添加uint32可能导致溢出(如果结果超过255,则8位会环绕并从0开始重新开始)。如果在您的情况下发生溢出,则可能是造成这种情况的原因。

来自http://www.cs.utah.edu/~regehr/papers/overflow12.pdf:“在C和C ++中,许多无符号整数溢出是定义明确的,但不可移植”

因此,您在currentReadPosition上提到的uint32更改是正确的解决方案。它使代码更具可移植性,并且除非有必要,否则通常是避免溢出的良好做法。