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

问题描述 投票:1回答:2

今天我有一位同事问我一个关于他的代码的问题,我无法回答。他正在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;
}
c static-variables
2个回答
2
投票

所以,今天早上我解开了这个谜......

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

我只是在看到这个行为之后再次看到这个问题,当我们通过他的结构调查时(看似)填充到11时它本应该没有填充...

谢谢大家的答案。


1
投票

将uint32添加到uint8可能会导致溢出(如果结果大于255,则8位环绕并从0开始重新开始)。如果您的情况发生溢出,那么这可能是解释。

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

所以,你在currentReadPosition上提到的变化是uint32是正确的解决方案。它使代码更具可移植性,并且除非必要,否则通常是避免溢出的良好实践。

© www.soinside.com 2019 - 2024. All rights reserved.