c / c++ 中 do {} while(0) 的 2 种用法

在这里插入图片描述

do {} while(0) 常见的两种用法

1.宏定义的多行定义;

2.代码的跳转,使用break跳过某些代码块。

用法1. 宏定义中定义多行

参考:https://bruceblinn.com/linuxinfo/DoWhile.html#:~:text=You%20may%20see%20a%20do,single%20statement%20can%20be%20used.
例子:

定义多行宏

#define foo \

	statement_1; \

	statement_2

调用宏

if (condition)

	foo;

实际会解释成下边这样,是不对的

if (condition)

	statement_1;

	statement_2;

如果替换成 do() {} while(0) 的形式就可以解决这个问题

#define foo \

	do { \

		statement_1; \

		statement_2; \

	} while (0)

这样解析后就变成

if (condition)

	do {

		statement_1;

		statement_2;

	} while (0);

性能方面,编译器会自动优化掉 while(0),所以不会造成额外的性能损失,gcc 提供了一种代替的新写法,如下

#define foo ({ \

	statement_1; \

	statement_2; \

})

用法2. 实现某些代码段的跳过

以 cocos 的一段源码作为示例,因为代码在 do {} while(0) 中所以可以在任意位置使用 break 跳出代码段。

void func() {
    bool reinited = false;
    do {
        if (CURLE_OK != errCode) {
            wrapper.second->setErrorProc(DownloadTask::ERROR_IMPL_INTERNAL, errCode, curl_easy_strerror(errCode));
            break;
        }

        // if the task is content download task, cleanup the handle
        if (wrapper.second->_headerAchieved) {
            break;
        }

        // the task is get header task
        // first, we get info from response
        if (false == _getHeaderInfoProc(curlHandle, wrapper)) {
            // the error info has been set in _getHeaderInfoProc
            break;
        }

        // after get header info success
        // wrapper.second->_totalBytesReceived inited by local file size
        // if the local file size equal with the content size from header, the file has downloaded finish
        if (wrapper.second->_totalBytesReceived &&
            wrapper.second->_totalBytesReceived == wrapper.second->_totalBytesExpected) {
            // the file has download complete
            // break to move this task to finish queue
            break;
        }
        // reinit curl handle for download content
        curl_easy_reset(curlHandle);
        _initCurlHandleProc(curlHandle, wrapper, true);
        mcode = curl_multi_add_handle(curlmHandle, curlHandle);
        if (CURLM_OK != mcode) {
            wrapper.second->setErrorProc(DownloadTask::ERROR_IMPL_INTERNAL, mcode, curl_multi_strerror(mcode));
            break;
        }
        reinited = true;
    } while (0);

    if (reinited) {
        continue;
    }
    curl_easy_cleanup(curlHandle);
    DLLOG("    _threadProc task clean cur handle :%p with errCode:%d", curlHandle, errCode);

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值