zoukankan      html  css  js  c++  java
  • 宏定义中的do{ }while(0)

    无论是Linux内核还是其他著名的c、c++库里都能见到 do{} while (0) 

    这样的写法看似没有意义,其实出自名家之手,是在宏定义里使用的 

    以前就了解到在程序里使用宏定义的函数后面的分号容易导致问题,今天算是深入认识了 

    先看一个简单的宏 

    #define SAFE_FREE(p) do {free(p);p=NULL;} while(0) 

    如果去掉了do... while(0) 

    即定义SAFE_FREE(p)为 

    #define SAFE_FREE(p) free(p);p=NULL; 

    那么下面的代码 

    if(NULL!=p) 

    SAFE_FREE(p) 

    else 

    //do something 

    将被展开为: 

    if(NULL!=p) 

    free(p);p=NULL; 

    else 

    //do something 

    这样就导致if后面有两条语句,第二条语句总会执行,且else不再与原来的if匹配 

    所以一般聪明的人在定义宏函数的时候会加上 {} 

    #define SAFE_FREE(p) { free(p);p=NULL;} 

    这样貌似解决了问题,可是还是有隐患 

    因为很多人习惯在C代码最后都加 ; 

    没有经验的人往往会不管那个SAFE_FREE(p)全是大写,直接在后面加上; 

    如 

    if(NULL!=p) 

    SAFE_FREE(p); 

    else 

    //do something 

    被展开为 

    if(NULL!=p) 

    { free(p);p=NULL;}; 

    else 

    //do something 

    这样 仍然导致if和else的匹配被破坏的情况 

    如果使用名家的方法 

    #define SAFE_FREE(p) do {free(p);p=NULL;} while(0) 

    那么 

    if(NULL!=p) 

    SAFE_FREE(p); 

    else 

    //do something 

    展开为 

    if(NULL!=p) 

    do 

    { free(p);p=NULL;} 

    while(0); 

    else 

    //do something 

    好了 这样就一切太平了 

    书上是这么说,可是我认为虽然采用了 

    #define SAFE_FREE(p) do {free(p);p=NULL;} while(0) 这样的定义 

    可是使用者要是突然意识到SAFE_FREE(p)是个宏,然后自作聪明没有在SAFE_FREE(p)后加; 

    如 

    if(NULL!=p) 

    SAFE_FREE(p) 

    else 

    //do something 

    这样展开 

    if(NULL!=p) 

    do 

    { free(p);p=NULL;}; 

    while(0) 

    else 

    //do something 

    这样while(0)后面没有; 仍然报错! 

    聪明反被聪明误,只因为还不够聪明。 

    解决问题最简单的方法就是良好的编程习惯 

    一个没有任何问题的if else结构就能解决所有的问题 

    if(NULL!=P) 

    {//do something } 

    else 

    { //do something } 

    就是两点,NULL!=P而不是p!=NULL ,还有就是齐全的{}匹配 

    说来容易,但是我们在网上甚至是名著里仍然很难看到完美的写法 

    不要偷懒,少打那么几个{},否则会付出更惨痛的代价
    Meet so Meet. C plusplus I-PLUS....
  • 相关阅读:
    script Ngrinder_TestRunnerInsertMysqlSingle.groovy
    nGrinder TestRunnerInsertMysqlSingle.groovy
    列表导航栏实例(02)——精美电子商务网站赏析
    【网络编程】之九、事件选择WSAEventSelect
    注册界面设计(01)——精美电子商务网站赏析
    列表导航栏实例(04)——精美模板赏析
    【网络编程】之十、重叠IO Overlapped IO
    CSS大小设置实例——盒子模型
    常用数据验证正则表达式释义(附:正则表达式常用符号)
    【网络编程】之八、异步选择WSAAsyncSelect
  • 原文地址:https://www.cnblogs.com/iplus/p/4467306.html
Copyright © 2011-2022 走看看