博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C 语言实现 RAII
阅读量:5248 次
发布时间:2019-06-14

本文共 1574 字,大约阅读时间需要 5 分钟。

尽管有许多的争议,但我还是觉得 C++ 中的 RAII 惯用法是个好东西,也是写 C 代码时唯一怀念的 C++ 特性。下面是一些 C 语言实现 RAII 的方法:

gcc

GCC 上可以使用

#define RAII_VARIABLE(vartype,varname,initval,dtor) \    void _dtor_ ## varname (vartype * v) { dtor(*v); } \    vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval) void example_usage() {  RAII_VARIABLE(FILE*, logfile, fopen("logfile.txt", "w+"), fclose);  fputs("hello logfile!", logfile);}

Windows

Windows 下可以使用SEH的__try/__finally,话说 Windows 下其实有不少东西还是挺方便的。

标准 C

为了更好的性能和可移植性,还可以使用setjmp/longjmp机制,一个简单封装如下,使用TRY/FINALLY即可

#define TRY do{ jmp_buf ex_buf__; switch( setjmp(ex_buf__) ){ case 0: while(1){#define CATCH(x) break; case x:#define FINALLY break; } default:#define ETRY } }while(0)#define THROW(x) longjmp(ex_buf__, x)

上面的代码里在switch里使用了while,使用的是Duff Device技术(如下所示)。这都是因为C语言中不允许gotoswitch语句的任何case处。

Duff Device

中给出形式是:

int n = (count + 7) / 8;   /* count > 0 assumed */switch (count % 8){case 0:    do { *to = *from++;case 7:     *to = *from++;case 6:     *to = *from++;case 5:     *to = *from++;case 4:     *to = *from++;case 3:     *to = *from++;case 2:     *to = *from++;case 1:     *to = *from++;          } while (--n > 0);}

这在C语言中是合法的,switch语句的唯一作用就是”陷落”到开始的合适位置开始执行。上例中这样一次比较可以执行8次拷贝操作,同时也不用关心count不能被8整除等问题。这种操作是一种特殊的循环展开机制(loop-unrolling mechanism)。(switch语句中的case实际上就是标签,这就容易理解了)。

这种技术在特别低层的代码(如驱动)或特定需求(如C语言实现RAII)时可以使用。

 

---------------------

作者:Virbox 技术博客
来源:Virbox 技术博客
原文:http://blog.virbox.com/2019/06/25/c-%E8%AF%AD%E8%A8%80%E5%AE%9E%E7%8E%B0-raii/
版权声明:本文为博主原创文章,转载请附上博文链接!

转载于:https://www.cnblogs.com/ssprotect/p/11089470.html

你可能感兴趣的文章
iOS-解决iOS8及以上设置applicationIconBadgeNumber报错的问题
查看>>
亡灵序曲-The Dawn
查看>>
Redmine
查看>>
帧的最小长度 CSMA/CD
查看>>
xib文件加载后设置frame无效问题
查看>>
编程算法 - 左旋转字符串 代码(C)
查看>>
IOS解析XML
查看>>
Python3多线程爬取meizitu的图片
查看>>
树状数组及其他特别简单的扩展
查看>>
zookeeper适用场景:分布式锁实现
查看>>
110104_LC-Display(液晶显示屏)
查看>>
httpd_Vhosts文件的配置
查看>>
php学习笔记
查看>>
普通求素数和线性筛素数
查看>>
PHP截取中英文混合字符
查看>>
【洛谷P1816 忠诚】线段树
查看>>
电子眼抓拍大解密
查看>>
poj 1331 Multiply
查看>>
tomcat7的数据库连接池tomcatjdbc的25个优势
查看>>
Html 小插件5 百度搜索代码2
查看>>