简体   繁体   English

C中的“with”宏

[英]“with” macro in C

I was looking for a macro that will resemble the with-construct. 我正在寻找一个类似于with-construct的宏。 The usage should be something like: 用法应该是这样的:

with (lock(&x), unlock(&x)) {
    ...
}

It might be useful for some other purposes. 它可能对其他一些用途有用。

I came up with this macro: 我想出了这个宏:

#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__)

It has 3 nested loops because it should: 它有3个嵌套循环,因为它应该:

  1. Initialize loop counter (C99 only, of course) 初始化循环计数器(当然只有C99)
  2. Possibly initialize variable _onenter (such as with (int fd=open(..), close(fd)) ) 可能初始化变量_onenter(例如with (int fd=open(..), close(fd))
  3. Allow break inside the code block. 允许在代码块内部break ( continue is allowed too. And the macro could be adjusted to assert() it out) (也允许continue 。宏可以调整为assert()它)

I used it on the code for the XV6 OS and it seems quite useful. 我在XV6操作系统的代码上使用它,它看起来非常有用。

My question is - what are the worst problems with such a macro? 我的问题是 - 这样一个宏的最大问题是什么? I mean, besides the mere usage of a C macro (especially one that implements new control-flow construct). 我的意思是,除了仅仅使用C宏(特别是实现新的控制流构造的宏)。

So far have found these drawbacks / problems: 到目前为止已发现这些缺点/问题:

  1. No support for return or goto (but it can save some goto s in kernel code) 不支持returngoto (但它可以在内核代码中保存一些goto
  2. No support for errors (such as fd < 0 ). 不支持错误(例如fd < 0 )。 I think this one is fixable. 我认为这个是可以解决的。
  3. gnu89 / c99 and above only (loop counter. the unique variable trick is not necessary) 仅限gnu89 / c99及以上版本(循环计数器。不需要唯一的变量技巧)
  4. Somewhat less efficient than simple lock-unlock. 比简单的锁定解锁效率低一些。 I believe it to be insignificant. 我认为这是微不足道的。

Are there any other problems? 还有其他问题吗? Is there a better way to implement similar construct in C? 有没有更好的方法在C中实现类似的构造?

That macro scares me. 那个宏吓到我了。 I'd prefer the traditional approach using goto s . 我更喜欢使用goto的传统方法

That approach is primitive, but most C programmers are familiar with the pattern and if they're not, they can understand it by reading the local code. 这种方法很原始,但大多数C程序员都熟悉这种模式,如果不是,他们可以通过阅读本地代码来理解它。 There is no hidden behavior. 没有隐藏的行为。 As a consequence, it's pretty reliable. 因此,它非常可靠。

Your macro is clever, but it would be new to most everybody and it comes with hidden gotchas. 你的宏很聪明,但它对大多数人来说都是新的,它带有隐藏的陷阱。 New contributors would have to be thought rules such as "don't return or goto out of a with block" and " break will break out of the with block, not out of the surrounding loop". 新的捐助将不得不被认为规则,如“不returngoto走出了一条与块”和“ break将爆发的与块,没出周围循环”。 I fear mistakes would be common. 我担心错误会很常见。

The balance would shift if you could add warnings for misuses of this construct to the compiler. 如果您可以将错误使用此构造的警告添加到编译器,那么余额将会发生变化。 With clang , that seems to be an option. 有了clang ,这似乎是一种选择。 In this case, misuses would be detected and your code would remain portable to other compilers. 在这种情况下,将检测到误用,并且您的代码将保持可移植到其他编译器。

If you're willing to restrict yourself to GCC and Clang, you can use the cleanup attribute. 如果您愿意将自己限制为GCC和Clang,则可以使用cleanup属性。 That would make your example look like this: 这会使你的例子看起来像这样:

lock_t x = NULL __attribute__((cleanup(unlock)));
lock(&x);

And unlock will be called with a pointer to the variable when it goes out of scope. 当变量超出范围时,将使用指向变量的指针调用unlock This is integrates with other language features like return and goto , and even with exceptions in mixed C/C++ projects. 它与其他语言功能(如returngoto )集成,甚至在混合C / C ++项目中也有例外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM