我在寻找一个类似于with结构的宏。 使用方法应该像这样:
with (lock(&x), unlock(&x)) {
...
}
这可能对其他用途有用。
我想出了这个宏:
#define __with(_onenter, _onexit, v) \
for (int __with_uniq##v=1; __with_uniq##v > 0; )\
for (_onenter; __with_uniq##v > 0; _onexit) \
while (__with_uniq##v-- > 0)
#define _with(x, y, z) __with(x, y, z)
#define with(_onenter, _onexit) _with(_onenter, _onexit, __COUNTER__)
它有3个嵌套循环,因为它应该:
- 初始化循环计数器(当然只适用于C99)
- 可能初始化_onenter变量(例如
with(int fd=open(..), close(fd))
) - 允许在代码块中使用
break
(也可以使用continue
。并且该宏可以调整为assert()
)
我的问题是 - 这样一个宏存在哪些最大的问题? 除了使用C宏(特别是实现新控制流结构的宏)之外。
到目前为止,我已经发现以下缺点/问题:
- 不支持
return
或goto
(但它可以节省内核代码中的一些goto
) - 不支持错误(如
fd <0
)。 我认为这个问题是可以解决的。 - 仅支持gnu89 / c99及以上版本(循环计数器。唯一的变量技巧不是必需的)
- 比简单的锁定/解锁效率略低。我认为这是微不足道的。
cleanup
- 听起来很有用。除了可怕之外,这个宏还有更具体的问题吗? - Elazarreturn
的支持似乎是一个致命问题,除非你在遵循严格的编码标准,禁止在函数中间使用return
语句。在with
块中使用return
看起来不起眼,但会在运行时造成严重后果。 - pdwreturn
是一个大问题(所以cleanup
更好)。但是goto
不需要同样严格的编码标准吗?在这方面,goto
有什么优势呢? - Elazarwith
块中return
或goto
出去”,以及“break
将会跳出with
块,而不是跳出周围的循环”。 - pdwgoto
语句是一个警告标志,而用户定义的宏不是。好的。 - Elazar