IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++的奇技淫巧之 do{}while(0) -> 正文阅读

[C++知识库]C/C++的奇技淫巧之 do{}while(0)

宏定义

  1. 避免空宏引起的warning
    内核中由于不同架构的限制,很多时候会用到空宏,在编译的时候,空宏会给出warning,为了避免这样的warning,就可以使用do{}while(0)来定义空宏:
#define EMPTYMICRO do{}while(0)
  1. 存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现。
#define MACRO_NAME(para) do{macro content}while(0)
  1. 如果出现在判断语句过后的宏,这样可以保证作为一个整体来实现。
    如果没有使用do{}while(0)定义这样的宏,进而在if语句后扩展这样的宏又没用{}括起来,会导致宏展开后语法逻辑错误。故这也是为什么单条if else语句也推荐使用{}括起来的原因之一。

使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。并且可以在宏之后添加分号,符合语句结束添加一个分号的习惯。

绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法并不会导致程序的性能降低。

另外,GCC提供了Statement-Expressions用以替代do{…}while(0); 所以在GCC中也可以这样定义宏:
注意,MSVC不支持这种语义。

#define DOSOMETHING() ({\\
        foo1(); \\
        foo2(); \\
})

一般这样的宏都是作为library的一部分出现的,而对于一个library的作者,他所要做的就是让其库具有通用性,强壮性,因此他不能有任何对库的使用者的假设,如其编码规范,技术水平等。

巧用do{}while(0)替代goto

C++中goto语句是被限制使用的。
c++原生不支持在goto和label中间定义自动变量,如map vector等复杂的,或者自定义类型变量。

class Test {
public:
    Test() {
        cout << "Test()" << endl;
    }
    ~Test() {
        cout << "~Test()" << endl;
    }
};
 
void func() {
	int i = 10;
    goto ERROR;
    Test t;
ERROR:
    return;
}

上面例子func方法中t执行了析构,未执行构造。在一些变量为vector等复杂的情况下,程序会触发core或者死循环,原因就是没经过构造过程容器内部地址是未初始化的,也就是常说的undefined behaviour。
在生产环境中,通过在goto之前定义变量解决了这个问题,但是本质上,c++对goto做了使用限制,因此在c++程序中不要轻易使用goto。
可以使用do{
//
break;
}whiile(0);替代goto的使用。

int foo()
{
    somestruct* ptr = malloc(...);
    do{
        dosomething...;
        if(error)
        {
            break;
        }
        dosomething...;
        if(error)
        {
            break;
        }
        dosomething...;
    }while(0);
    free(ptr);
    return 0;
}

这里将函数主体使用do()while(0)包含起来,使用break来代替goto,后续的处理工作在while之后,就能够达到同样的效果。

https://blogread.cn//it/article/5907
https://blog.csdn.net/fxy0325/article/details/89856623

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:06:35  更:2022-11-05 00:08:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:37:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码