C中的棘手宏

时间:2014-10-30 14:06:21

标签: c embedded powerpc

我有一个关于PowerPC的声明,并且不知道它是如何工作的

#define XOR(A,D) (*(volatile unsigned int*)(volatile void*)((unsigned char*)0UL + (A)) ^= (D))

被称为(例如)

unsigned int a = 3;
unsigned int b = 50;
XOR((unsigned int)&a,b);

使用标准PC的gcc它不能编译,在我的环境中它确实如此,所以我问自己:wtf ...

3 个答案:

答案 0 :(得分:2)

在硬编码地址切换位似乎是一个不必要的复杂宏。这些地址可能是存储器映射的寄存器地址。 AD是这里的线索:A =地址,D =数据。因此,通常如果您在地址0x100处有一个寄存器并且想要切换其最低有效位,则可以编写如下内容:

XOR(0x100, 0x01);

更简单的版本就是:

#define XOR(A, D) ((*(volatile int *)(A)) ^= (D))

目前尚不清楚为什么原作者使用多个强制转换并将硬编码地址添加到NULL指针。猜测,前者可能会在那里摆脱编译器警告,后者可能在某些时候允许不同的寄存器基地址。

答案 1 :(得分:2)

这是一种难以置信的混淆写作方式

*(volatile uint32_t*)a ^= b;

(我选择了uint32_t,因为据说CPU是PowerPC)

每当你看到有人试图用他们自己模糊的宏语言重新发明C语言时,你可以确定该程序质量有问题。在这种情况下,很明显程序员对C的工作方式非常不安全,而且我认为其余代码存在很多怀疑。

在这种情况下,请勿使用类似函数的宏。

答案 2 :(得分:-2)

额外的转换是减少MISRA检查警告。 Here是参考。