• do{…}while(0) 的秒用


    在linux内核代码中,有这样的宏定义:
    #define DUMP_WRITE(addr,nr) do{ memcpy(bufp,addr,nr); bufg+=nr; }while(0)

    这个宏定义意味着引用这个宏操作时会执行循环体一次,但为什么要定义成这样的怪形式呢?

    我们看看其他几种形式的宏定义:
    #define DUMP_WRITE(addr,nr)  memcpy(bufp,addr,nr);  bufp+=nr;

    这种宏定义行不行?

    我们把这个宏放到一个语境中:
    if (addr)

        DUMP_WRITE(addr,nr);

    else

        do_something_else();

    结果发现编译会出错,为什么?

    把宏展开,上述语句块变为:
    if (addr)

        memcpy(bufp,addr,nr); bufp+=nr;

    else

        do_something_else();

    这样就会在if-else语句之间加了一条语句bufp+=nr;形成类似于 if-dosomething-else 的语句。这样else将无法找到与之匹配的 if,所以编译器会报错。

    换种引用形式:
    if(!addr)

        do_something_else();

    else

        DUMP_WRITE(addr,nr);

    这样虽然编译能通过,但是问题会更严重,因为bufp+=nr; 会始终被执行。

    到这里,我们可能马上会想到在宏定义中加一个大括号:

    #define DUMP_WRITE(addr,nr)  {memcpy(bufp,addr,nr);  bufp+=nr;}

    这样能行吗?我们放到语境中测试下:

    if (addr)

        DUMP_WRITE(addr,nr);

    else

        do_something_else();

    依然编译出错,为什么呢?

    将宏展开之后为:

    if (addr)

        {memcpy(bufp,addr,nr);  bufp+=nr;};

    else

        do_something_else();

    这里在if-else语句中插入了一条空语句:if-空语句-else,同样的编译器也不能为 else 找到与之匹配的 if 语句。所以依然会编译报错。

    而使用下面这种格式的宏定义,则完全没问题。

    #define DUMP_WRITE(addr,nr) do{ memcpy(bufp,addr,nr); bufg+=nr; }while(0)

  • 相关阅读:
    php数组转换成js可用的数组的两种方式
    常用正则表达式--------------[拿把小刀,强大自己]
    AngularJs 相应回车事件
    常见的关系型数据库和非关系型数据库及其区别
    CMDB资产采集
    GB和GiB的区别
    python枚举详解
    python保留两位小数
    详解TCP三握四挥
    npm run dev 和 npm run serve
  • 原文地址:https://www.cnblogs.com/ljf181275034/p/1957666.html
Copyright © 2020-2023  润新知