我是靠谱客的博主 真实小蚂蚁,最近开发中收集的这篇文章主要介绍do...while(0)的用法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1:定义复杂宏并避免编译错误

当你定义了一个这样的宏

#define fun() fun1(); fun2()

代码被翻译前后的样子

// 翻译前
fun();

// 翻译后
fun1();
fun2();

这是没有什么问题的,但是当加上if条件判断后,情况就发生了一些微妙的变化

// 翻以前
if (condition == TRUE)
    fun();

// 翻译后
if (condition == FALSE)
    fun1();
fun2();

可以看到,逻辑已经发生了变化,不是我们期望的执行逻辑了。

那如果给宏加上“{}”是不是就可以呢?

#define fun() { fun1(); fun2(); }

1:
// 翻译前
if (condition == TRUE)
    fun();

//翻译后
if (condition == TTRUE) {
    fun1();
    fun2();
};

2:
// 翻译前
if (condition == TRUE)
    fun();
else
    other();

//翻译后
if (condition == TTRUE) {
    fun1();
    fun2();
};
else 
    other();

可以看到多了一个冒号,已经发生了编译错误。

但是如果给宏加上do...while(0),以上所有问题都将迎刃而解:

#define fun() do { fun1(); fun2(); } while(0)

1:
// 翻译前
if (condition == TRUE)
    fun();

//翻译后
if (condition == TTRUE) 
    do { 
            fun1(); 
            fun2(); 
    } while(0);

2:
// 翻译前
if (condition == TRUE)
    fun();
else
    other();

//翻译后
if (condition == TTRUE) 
    do { 
            fun1(); 
            fun2(); 
    } while(0);
else 
    other();

借用大佬们的一句话进行总结:Linux和其它代码库里的宏都用do/while(0)来包围执行逻辑,因为它能确保宏的行为总是相同的,而不管在调用代码中使用了多少分号和大括号。 

2:代替goto实现更可控的跳转

当我们在C/C++中处理一段重要的逻辑的时候,有时候总是会出现这样那样的意外情况,此时就需要我们有一个兜底方案来处理意外来临时的烂摊子,比如置空对象、回收内存等,如果用goto来实现,将会是这个样子:

void* execute() {
    int *p_int = new int;
    void *ptr = malloc(1024);

    int ok = fun0(ptr);
    if (!ok) {
        goto errorhandle;
    }

    ok = fun1(ptr);
    if (!ok) {
        goto errorhandle;
    }

    ok = fun2(ptr);
    if (!ok) {
        goto errorhandle;
    }

    delete p;
    p = nullptr;
    return ptr;

errorhandle:
    delete p;
    p = nullptr;
    free(ptr);
    return nullptr;
}

goto语句太多,虽然goto可增加灵活性,但是代码读起来很恶心,同时执行起来也很危险。如果用do...while(0)来做一些改变,将会是这样:

void* execute() {
    int *p_int = new int;
    void *ptr = malloc(1024);

    do {
            int ok = fun0(ptr);
            if (!ok) {
                break;
            }

            ok = fun1(ptr);
            if (!ok) {
                break;
            }

            ok = fun2(ptr);
            if (!ok) {
                break;
            }

            delete p;
            p = nullptr;
            return ptr;
    } while(0);
    
    
    delete p;
    p = nullptr;
    free(ptr);
    return nullptr;
}

向大佬们学习,奇技淫巧太好用啦! 

最后

以上就是真实小蚂蚁为你收集整理的do...while(0)的用法的全部内容,希望文章能够帮你解决do...while(0)的用法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部