宏do{} while(0)的作用

宏do{} while(0)的作用

参考链接:https://github.tiankonguse.com/blog/2014/09/30/do-while.html

今天学到1个类函数宏,有很巧妙的用处:

#define FOO(X) do{ something; } while(0)

它至少有如下3种作用,分别是避免宏的错误使用避免使用goto对空宏的替代

1 避免宏的错误使用

为了理解它,我们先从一个普通的类函数宏看起,假设函数体有多行代码:

#define FOO(X, Y) x++;y++;

int main(){
    ...
    if (...)
        FOO(x, y);

    //上面代码会被展开为:
    if (...)
        x++;
    y++;;
}

此时if只能限定1行代码,导致错误(我们可能会认为类函数宏FOO只有1行代码,所以在if出现时,可能不会用大括号将FOO括起来)。

于是我们将函数体用大括号括起来后,又出现了新的问题,我们一般习惯在宏的最后添加分号,所以出现如下情况:

#define FOO(X, Y) {x++;y++;}

int main(){
    ...
    if (...)
        FOO(x, y);

    //上面代码会被展开为:
    if (...){
        x++;
        y++;
    }; //此处的分号编译报错
}

我们希望找到1个合适的宏定义,既有大括号,又能不受最后添加分号的影响,于是do {...;} while(0)的形式出现了。

它还有另一形式:#define FOO(X) if (1) { something; } else

2 error跳转,避免goto的使用

非常巧妙!它可以作为goto语句的替代,从而满足编程规范的要求(禁止使用goto)。

goto语句一般用于出错时跳转到程序末尾,而循环break时,也是跳出循环(到达循环的"末尾")。由此,我们可以有如下代码:

使用goto的情况
void foo(){
    if(error){
        goto END;
    }
    dosomething...;
    if(error){
        goto END;
    }
    dosomething...;
 
END:
    dosomething...;
    return 0;
}
不使用goto的情况
int foo(){
    do{
        if(error) {
            break;
        }
 
        dosomething...;
        if(error){
            break;
        }
        dosomething...;
    }while(0);
    dosomething...;
    return 0;
}

3 替代空宏

空宏定义(编译报Warning):#define EMPTYMACRO

替代的空宏定义(无副作用):#define EMPTYMACRO do {} while (0)

posted @ 2024-03-19 21:47  Digitzh  阅读(92)  评论(0)    收藏  举报