两种类型的C #define之间的区别

时间:2015-10-31 14:54:59

标签: c c-preprocessor

有人可以解释一下以下定义之间的区别:

#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定义提供了相同的结果?

2 个答案:

答案 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 + 1pchar *int *会给出不同的地址。因此,如果INTR_BASE_VAL(x)评估的格式与unsigned long的大小不同,则这两种格式会产生不同的结果。

在这种情况下,您应该使用第一个表单。