【问题标题】:Type dereferencing type-punned pointer will break strict-aliasing rule类型取消引用类型双关指针将破坏严格别名规则
【发布时间】:2016-07-19 18:58:14
【问题描述】:

我在这段代码中有一个编译器警告('类型取消引用类型双关指针会破坏严格别名规则'):

volatile uint8_t Buff[READ_BUFF_SIZE];

#define   LD_DWORD(ptr)      (DWORD)(*(DWORD*)(BYTE*)(ptr))

ChunkID = LD_DWORD(&Buff[0]); <-- here is warning

我使用的是 32 位 Cortex M0。

尽管有警告,但它工作正常。我的问题是,警告可以解决吗?

【问题讨论】:

  • 了解严格别名规则。这是一个广泛的主题。
  • ...您是否尝试将警告粘贴到您最喜欢的搜索引擎中?还是这个网站?

标签: c


【解决方案1】:

将没有分配存储持续时间的对象重新解释为其他(不兼容)类型的对象是未定义的行为。

在您的示例中,Buff 的类型为 uint8_t,具有静态或自动存储持续时间,被重新解释为类型 DWORD。这些类型不兼容1,行为未定义。

您应该简单地将Buff 定义为您打算使用的类型,它似乎是DWORD

volatile DWORD Buff[READ_BUFF_SIZE];

然后您不需要宏来访问,只需使用内置运算符即可:

ChunkID = Buff[0];

1 即使我们假设2 uint8_t 被定义为unsigned char,它可以给任何类型起别名,DWORD 类型也不能给unsigned char 起别名。

2 标准允许类型uint8_t 不定义为unsigned char,即使CHAR_BIT 为8。请参阅扩展整数类型。

【讨论】:

  • 是的,这是一个不错的答案——但它不会使问题不再重复。
  • @JonathanLeffler 只有“体面”? :-) 是的,我猜这是“有点儿”。
  • 好的,明白了!我一直想知道为什么会产生警告。感谢您的链接,我阅读了一些并理解了。我不能将我的缓冲区声明为 uint8 以外的内容,因为有许多例程按原样使用它。但在其他几个中,数据作为 uint16、uint32 等是有意义的。我通过在原始缓冲区上使用联合来更优雅地解决它。谢谢。
  • @user1797147 你可以使用 malloc。分配的内存更灵活。
猜你喜欢
  • 2011-11-29
  • 1970-01-01
  • 2014-12-30
  • 2016-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
相关资源
最近更新 更多