可以用变量体定义类似函数的宏吗?

Rei*_*ica 8 c macros mutex

我一直在寻找用于定义宏的GCC文档,它看起来像我想要的是不可能的,但我想如果是,有人在这里会知道.

我想要做的是定义这个宏:

synchronized(x) {
  do_thing();
}
Run Code Online (Sandbox Code Playgroud)

其中扩展为:

{
    pthread_mutex_lock(&x);
    do_thing();
    pthread_mutex_unlock(&x);
}
Run Code Online (Sandbox Code Playgroud)

在C++中,我可以创建一个SynchronizedBlock在其构造函数中获取锁定并在析构函数中解锁的对象,但我不知道如何在C中执行此操作.

我意识到我可以在表单中使用函数指针synchronized(x, &myfunction);,但我的目标是使一些C代码看起来尽可能像Java一样.是的,我知道这是邪恶的.

Joe*_*e D 16

编辑:改为nategoose的版本

#define synchronized(lock) \
for (pthread_mutex_t * i_#lock = &lock; i_#lock; \
     i_#lock = NULL, pthread_mutex_unlock(i_#lock)) \
    for (pthread_mutex_lock(i_#lock); i_#lock; i_#lock = NULL)
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

synchronized(x) {
    do_thing(x);
}
Run Code Online (Sandbox Code Playgroud)

甚至没有牙套

synchronized(x)
    do_thing();
Run Code Online (Sandbox Code Playgroud)

  • 这同时令人惊讶和恐怖.我从来没有想过这一点. (5认同)
  • 这应该解决两个问题:`#definefine(lock)`\`for(pthread_mutex_t*i_ =&lock; i_; i_ = NULL)`\`for(pthread_mutex_lock(i_); i_;`\`pthread_mutex_unlock(i_),i_ = NULL)` (3认同)
  • 此外,这有一些关于流量控制的缺陷.`break`,`continue`,`goto`和`return`可能与程序员期望的不同:前两个将只在宏内部终止`for`,而不是封闭构造.后两个将跳过`pthread_mutex_unlock`,因此锁不会被释放. (3认同)
  • 或者,使用单个`for()`并检查是否已获取锁:`#define同步(MUTEX)\ for(pthread_mutex_t*synchronized_mutex_ =&MUTEX;\synchronized_mutex_ &&!pthread_mutex_lock(synchronized_mutex_);\pthread_mutex_unlock(synchronized_mutex_) ,synchronized_mutex_ = 0)` (2认同)
  • 此版本不允许您嵌套同步块.为了解决这个问题,我将`i_`更改为`i _ ## lock`(所以`synchronized(some_lock)`扩展为`for(pthread_mutex_t*i_some_lock =&some_lock; ...`.作为奖励,`synchronized(some_lock)synchronized( some_lock){}`会导致编译错误. (2认同)
  • @nategoose,@ Brendan,有一些方法可以使这些宏对`break`等更加可控,并且可以在不使用像`__COUNTER__`这样的扩展的情况下正确嵌套它们.P99将为此提供一般框架:http://p99.gforge.inria.fr/p99-html/group__preprocessor__blocks_gaa864200ae44c5666b1c42cfa60836a63.html#gaa864200ae44c5666b1c42cfa60836a63 (2认同)

Jon*_*han 6

这是一个开始,但您可能需要调整它:

#define synchronized(lock, func, args...) do { \
    pthread_mutex_lock(&(lock)); \
    func(##args); \
    pthread_mutex_unlock(&(lock)); \
} while (0)
Run Code Online (Sandbox Code Playgroud)

像这样使用(不幸的是,不是您想要的类似 Java 的语法):

synchronized(x, do_thing, arg1, arg2);
Run Code Online (Sandbox Code Playgroud)