zoukankan      html  css  js  c++  java
  • 关于宏的一些内容的总结

    1. 为什么宏定义里经常出现 do {...} while (0) 

    Answer:

    用一句话概括就是:使用do{...}while(0)构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。

    比如

    #define foo(x) i++; i--

    如下调用

    foo(wolf);

    就会被扩展为

    i++; i--;

    但是如果这样调用

    if (!feral)

        foo(wolf);
     那么扩展后就是

    if (!feral)

        i++;

    i--;

    不符合原意了。

    那么为什么不用大括号直接把宏包围起来呢?例如:

    #define foo(x) { i++; i--; }

    考虑如下情况:

    if (!feral)

        foo(wolf);
    else
        bin(wolf);
     
    扩展后为:
    if (!feral) {
        i++;
        i--;
    };
    else
        bin(wolf);
     
    就有语法错误了。
     
    所以,Linux和其它代码库里的宏都用do/while(0)来包围执行逻辑,因为它能确保宏的行为总是相同的,而不管在调用代码中使用了多少分号和大括号。
     
    其他 do {...} while (0) 的作用包括:
    1. 使用break来代替goto的跳转,比如:
    int foo() 
    { 
        somestruct* ptr = malloc(...); 
        
        dosomething...; 
        if(error) 
        { 
            goto END; 
        } 
        
        dosomething...; 
        if(error) 
        { 
            goto END; 
        } 
        dosomething...; 
        
    END: 
        free(ptr); 
        return 0; 
        
    } 

    替换为

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

    2. 避免变量作用域的冲突,在 do{}while(0) 定义变量

    3. 可以定义空的宏(避免警告)

    #define EMPTYMICRO do{}while(0) 

  • 相关阅读:
    MySql—修改权限
    linux apache Tomcat配置SSL(https)步骤
    spark-shell启动错误
    spark
    Ubuntu不能连接网络
    NSGA-II算法学习
    SpringBoot集成mybatis,同时读取一个数据库中多个数据表
    设置虚拟机ip地址
    发送邮件
    spring session
  • 原文地址:https://www.cnblogs.com/charlesblc/p/5440901.html
Copyright © 2011-2022 走看看