【问题标题】:Assigning value in C macro在 C 宏中赋值
【发布时间】:2022-11-02 17:14:49
【问题描述】:

可以在 C 宏中赋值(即在宏中有左值)吗?例如,我想根据指定的位位置将一个数字的位设置为1。这样做可以吗:

#define SET_BIT(data, pos)  ((data) |= (1U << (pos)))

我已经对此进行了测试并且它有效,但我觉得我在这里如履薄冰,如果我习惯了这样的宏,我最终会遇到问题。

【问题讨论】:

    标签: c macros


    【解决方案1】:

    一旦预处理器在代码中完成了宏的扩展,宏将不存在。如果你有这样的声明

    SET_BIT(some_data, some_pos);
    

    然后它将被替换为

    ((some_data) |= (1U << (some_pos)));
    

    在被解析和编译的代码中。

    简而言之,在宏中进行赋值是非常好的。


    第一个SET_BIT_TO_VAL 宏的问题:

    #define SET_BIT_TO_VAL(data, pos, val)  (CLEAR_BIT(data, pos); (data) |= (1U << (pos)))
    

    是您将语句放在括号内,就像它们是表达式一样。所以这不会建立。

    在宏中对语句进行分组的常用方法是将它们包装在 do { ... } while(0) 循环中:

    #define SET_BIT_TO_VAL(data, pos, val) 
        do {                               
            CLEAR_BIT(data, pos);          
            SET_BIT(data, pos);            
        } while (0)
    

    【讨论】:

    • 还有一个问题,如何链接两个赋值宏?例如,如果我有一个清除位的宏:#define CLEAR_BIT(data, pos) ((data) &amp;= ~(1U &lt;&lt; (pos))),并且想要清除位,然后在另一个宏中设置位,则括号有问题:#define SET_BIT_TO_VAL(data, pos, val) (CLEAR_BIT(data, pos); (data) |= (1U &lt;&lt; (pos)))。在这种情况下是否可以将宏放在花括号中,例如:#define SET_BIT_TO_VAL(data, pos, val) {CLEAR_BIT(data, pos); (data) |= (1U &lt;&lt; (pos));}
    • @A6SE 更新了答案以帮助您发表评论。
    猜你喜欢
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多