有人可以解释一下以下定义之间的区别:
#define ADDR_VAL(x) (*((volatile unsigned long *)(x)))
和
#define ADDR_VAL(x) (*((volatile unsigned long *)x))
在我的情况下,大部分用法如下:
#define INTR_SRC(x) ADDR_VAL(INTR_BASE_VAL(x) + 0x180)
INTR_SRC(0) = 0x24ul;
假设INTR_BASE_VAL(x)
是一个计算为0x1A002D00
的值,上述两个被管理的ADDR_VAL(x)
定义是否都为INTR_SRC
定义提供了相同的结果?
答案 0 :(得分:3)
第一个将x
表达式转换为volatile unsigned long *
,而第二个表达式只展示它的第一部分。
例如,在第一种情况下,整个INTR_BASE_VAL(x) + 0x180
将转换为volatile unsigned long *
而在第二种情况下 - 仅INTR_BASE_VAL(x)
。
展开的第一个表达式:
(*((volatile unsigned long *)(INTR_BASE_VAL(x) + 0x180)))
整个表达式被转换然后解除引用
展开的第二个表达式:
(*((volatile unsigned long *)INTR_BASE_VAL(x) + 0x180))
只有第一部分被转换,但整个事物(INTR_BASE_VAL(x)
转换为指针加上的值0x180
)被取消引用。
答案 1 :(得分:0)
鉴于用法
ADDR_VAL(INTR_BASE_VAL(x) + 0x180)
第一种形式将扩展为
(*((volatile unsigned long *)(INTR_BASE_VAL(x) + 0x180)))
表达式INTR_BASE_VAL(x) + 0x180
会转换为volatile unsigned long *
类型,然后解除引用。
第二种形式扩展为
(*((volatile unsigned long *) INTR_BASE_VAL(x) + 0x180))
表达式INTR_BASE_VAL(x)
转换为volatile unsigned long *
类型,0x180
已添加到结果中,并且添加的结果将被取消引用。
它有所作为吗?取决于INTR_BASE_VAL(x)
的类型。请记住,指针算法基于指向对象的类型:如果p + 1
是p
与char *
,int *
会给出不同的地址。因此,如果INTR_BASE_VAL(x)
评估的格式与unsigned long
的大小不同,则这两种格式会产生不同的结果。
在这种情况下,您应该使用第一个表单。