【问题标题】:Difference between 2 types of C #define [duplicate]两种C#define之间的区别[重复]
【发布时间】:2015-10-31 14:54:58
【问题描述】:

谁能解释一下以下定义之间的区别:

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

【问题讨论】:

    标签: c c-preprocessor


    【解决方案1】:

    第一个将所有 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 的值)被取消引用。

    【讨论】:

    • 所以我在第二个中说结果值将是 INTR_BASE_VAL(x) + 0x180*(sizeof(unsigned long)) 的取消引用值是正确的,而在第一个中它相当于(INTR_BASE_VAL(x) + 0x180) 的取消引用值
    • @Quest,请检查我的编辑。我不太确定您的评论中 sizeof(unsigned long) 的出处。
    【解决方案2】:

    根据使用情况

    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) 的类型最终是什么。请记住,指针运算基于指向对象的类型:如果pchar *int *p + 1 将给出不同的地址。因此,如果INTR_BASE_VAL(x) 计算的类型与unsigned long 的大小不同,这两种形式将给出不同的结果。

    在这种情况下,您应该使用第一种形式。

    【讨论】:

      猜你喜欢
      • 2012-08-25
      • 2012-10-11
      • 2011-07-09
      • 2019-06-05
      • 2016-11-29
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 2012-12-14
      相关资源
      最近更新 更多