读书频道 > 网站 > 网页设计 > Linux设备驱动开发详解:基于最新的Linux 4.0内核
3.5.3 do { } while(0) 语句
15-08-30    下载编辑
收藏    我要投稿   
本书首先介绍Linux设备驱动的基础。第1章简要地介绍了设备驱动,并从无操作系统的设备驱动引出了Linux操作系统下的设备驱动,介绍了本书所基于的开发环境。第2章系统地讲解了Linux驱动工程师应该掌握的硬件知识,立即去当当网订购
在Linux内核中,经常会看到do {} while(0)这样的语句,许多人开始都会疑惑,认为do {} while(0)毫无意义,因为它只会执行一次,加不加do {} while(0)效果是完全一样的,其实do {} while(0)的用法主要用于宏定义中。
 
这里用一个简单的宏来演示:
 
#def?ine SAFE_FREE(p) do{ free(p); p = NULL;} while(0)
假设这里去掉do...while(0),即定义SAFE_DELETE为:
#def?ine SAFE_FREE(p) free(p); p = NULL;
那么以下代码:
if(NULL != p)
   SAFE_DELETE(p)
else
   .../* do something */
会被展开为:
if(NULL != p)
   free(p); p = NULL; 
else
   .../* do something */

 

展开的代码中存在两个问题:
 
1)因为if分支后有两个语句,导致else分支没有对应的if,编译失败。
 
2)假设没有else分支,则SAFE_FREE中的第二个语句无论if测试是否通过,都会执行。
 
的确,将SAFE_FREE的定义加上{}就可以解决上述问题了,即:
 
#def?ine SAFE_FREE(p) { free(p); p = NULL;}
这样,代码:
if(NULL != p)
    SAFE_DELETE(p)
else
    ... /* do something */
会被展开为:
if(NULL != p)
   { free(p); p = NULL; }
else
    ... /* do something */

 

但是,在C程序中,在每个语句后面加分号是一种约定俗成的习惯,那么,如下代码:
 
if(NULL != p)
    SAFE_DELETE(p);
else
    ... /* do something */
将被扩展为:
if(NULL != p)
   { free(p); p = NULL; };
else
   ... /* do something */

 

 
这样,else分支就又没有对应的if了,编译将无法通过。假设用了do {} while(0)语句,情况就不一样了,同样的代码会被展开为:
 
if(NULL != p)
    do{ free(p); p = NULL;} while(0);
else
    ... /* do something */

 

而不会再出现编译问题。do{} while(0)的使用完全是为了保证宏定义的使用者能无编译错误地使用宏,它不对其使用者做任何假设。
 
 
err3:
    unregister_c();
err2:
    unregister_b();
err1:
    unregister_a(); 
err:
    return ret;  

 

 
这种将goto用于错误处理的用法实在是简单而高效,只需保证在错误处理时注销、资源释放等,与正常的注册、资源申请顺序相反。
点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1.3 功能
下一篇:1.5 小结
相关文章
图文推荐
JavaScript网页动画设
1.9 响应式
1.8 登陆页式
1.7 主题式
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站