这个C宏是什么意思?

What does this C macro mean?

查看fm_transmitter源代码,我偶然发现了这个经常使用的宏。

#define ACCESS(base, offset) *(volatile unsigned*)((int)base + offset)

我猜它是一个基数和偏移量的总和,转换为 int,然后重新转换为无符号指针,然后再次转换为指针?

此宏提供对以字节为单位测量的偏移量的访问。您可以将其重写为

#define ACCESS(base, offset) *(volatile unsigned*)&((char*)base)[offset]

只是原始版本通过 int 类型而不是 char* 类型进行运算。

请注意,使用此宏可能会调用未定义的行为:不能保证生成的指针正确对齐,并且如果数据以 int 变体以外的其他类型写入,则违反了也有严格的别名规则。

还有,选择int来做指针运算是一个很糟糕的选择,至少应该通过size_tuintptr_t来计算,以保证指针在转换为整数类型期间不会被截断。我重写的版本没有这个具体问题,但是,两个版本都存在未定义行为的危险。

最后,正如 Olaf 在评论中正确指出的那样,转换为 volatile unsigned* 也是一个坏主意,因为这种类型的宽度是实现定义的。转换为 volatile uint32_t* 可能更适合与硬件通信。