查看fm_transmitter源代码,我遇到了这个经常使用的宏。
#define ACCESS(base, offset) *(volatile unsigned*)((int)base + offset)
我猜它的基数和偏移量的总和被转换为int,然后重新转换为无符号指针然后再次指针?
答案 0 :(得分:3)
此宏提供对以字节为单位的偏移量的访问。您可以将其重写为
#define ACCESS(base, offset) *(volatile unsigned*)&((char*)base)[offset]
仅原始版本通过int
类型而不是char*
类型执行算术。
请注意,使用此宏可能会调用未定义的行为:无法保证生成的指针正确对齐,如果数据是以int
变体之外的其他类型编写的,则它是违规行为严格的别名规则。
此外,选择int
进行指针运算是一个非常糟糕的选择,计算至少应该通过size_t
或uintptr_t
进行,以保证指针不是在转换期间截断为整数类型。我的重写版本没有这个特定的问题,但是,两个版本都存在未定义行为的危险。
最后,正如Olaf在评论中正确指出的那样,转换为volatile unsigned*
也是一个坏主意,因为此类型的宽度是实现定义的。对volatile uint32_t*
的强制转换可能更适合与硬件进行通信。