这个C宏是什么意思?

时间:2016-01-16 22:00:44

标签: c c-preprocessor

查看fm_transmitter源代码,我遇到了这个经常使用的宏。

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

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

1 个答案:

答案 0 :(得分:3)

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

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

仅原始版本通过int类型而不是char*类型执行算术。

请注意,使用此宏可能会调用未定义的行为:无法保证生成的指针正确对齐,如果数据是以int变体之外的其他类型编写的,则它是违规行为严格的别名规则。

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

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