分配时宏值发生了变化

时间:2012-12-16 11:43:06

标签: c

我不知道如何表达我的问题。代码如下,请告诉我为什么a的值发生了变化?在我看来,GET macro只返回a的值,而不是a的地址......

#include <stdio.h>

#define GET(addr) (*(int *)(&addr))

int main()
{
    int a = 10;
    GET(a) = 20;
    printf("%d\n", a);
}

4 个答案:

答案 0 :(得分:3)

当您展开宏时,您会得到:

(*(int *)(&a)) = 20

忘记(int *),你得到

(*(&a)) = 20

等于:

a = 20;

因此,您正在更改a

的值

答案 1 :(得分:1)

GET(a) = 20行扩展为:

(*(int *)(&a)) = 20;

让我们摆脱多余的演员和外括号:

*(&a) = 20;

这显然是对a的赋值,因为它等同于:

a = 20;

如果你的目标是防止意外使用GET()作为左值,你可以改变它:

#define GET(addr) ((int)addr)

有了这个,尝试编译代码失败了

test.c:8:12: error: lvalue required as left operand of assignment

答案 2 :(得分:1)

说你有:

int *b = ...;
*b = 10;

以上所做的是将10分配给b指向的整数。

你的宏几乎完全相同,b替换为&a(以及无操作演员)。

答案 3 :(得分:1)

取消引用指针的结果是L-value,因为它有一个地址;它当然可以分配。

考虑一个更简单的示例:如果p是数组或指针,您当然可以分配给p[0],如

p[0] = 20;

现在回想一下p[0]*p相同。现在展开你的宏:

*((int*)&a) = 20;

这相当于

(&a)[0] = 20;

这肯定是a本身的有效(尽管有些非正统)的分配。