当前位置:网站首页>C 语言实现 RAII
C 语言实现 RAII
2022-07-21 10:26:00 【senseshield】
尽管有许多的争议,但我还是觉得 C++ 中的 RAII 惯用法是个好东西,也是写 C 代码时唯一怀念的 C++ 特性。下面是一些 C 语言实现 RAII 的方法:
gcc
GCC 上可以使用cleanup 扩展实现
#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语言中不允许goto
到switch
语句的任何case
处。
Duff Device
C-FAQ中给出形式是:
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/
版权声明:本文为博主原创文章,转载请附上博文链接!
边栏推荐
- There are 8778 authors in a paper: each person writes 5 words, and the signature takes 17 pages
- Basic process of generating digital image
- SAP ABAP parsing function text of Excel file_ CONVERT_ XLS_ TO_ SAP single step analysis
- Write to yourself: 2021 version of the transfer reference book
- 【性能优化】MySQL常用慢查询分析工具
- [machine learning] dimension reduction technology PCA
- Text detection - traditional
- Network development kit Libpcap
- Mutex和智能指针替代读写锁
- open和fopen的区别
猜你喜欢
CodeQL使用流程
MySQL45讲笔记-字符串前缀索引&MySQL刷脏页分析
Educational codeforces round 70 a question you are given two binary strings
Bootloader series 4 - clock initialization
jenkins:构建的时候进入子目录然后在进行mvn操作
Multi process single thread multi port TCPUDP three-layer protocol forwarding
Transplant tslib-1.4 to mini2440 development board
[performance optimization] MySQL common slow query analysis tools
Packet format of network packets
2022全球开发者薪资曝光:中国排第19名,平均年薪23,790美元
随机推荐
matplotlib(六)三维作图
Virtual and pure virtual destructions
Python predicts the model code demo of the next number through the first three numbers
剑指 Offer 52. 两个链表的第一个公共节点
虚析构和纯虚析构
Cloud native sig live broadcast: About CNI and hybridnet core technology sharing | issue 35
[paper notes] modeling task relationships in multi task learning with multi gate mixture of experts
From scratch implement crnn using pytorch: read training data
The difference between open and fopen
mysql创建新用户并授权
delete的使用
写给自己:2021版调参上分手册
云原生 SIG 直播:关于 cni 与 hybridnet 核心技术分享 | 第 35 期
网络开发包 libpcap
为配置SSL,自制CA证书
Mutex and smart pointer replace read-write lock
Codeforces Round #579 (Div. 3) A 、B、E
[machine learning] dimension reduction technology PCA
剑指 Offer 53 - I. 在排序数组中查找数字 I
This price is fragrant enough! Lingyao 142022 shadow cyan glaze spike: 12th generation core +2.8k OLED screen