【问题标题】:C variable assigned with return value from scope block?C变量分配有范围块的返回值?
【发布时间】:2013-07-01 16:32:48
【问题描述】:

我偶然发现了似乎无效的代码,但显然是因为它位于Mono codebase for already 2 years 中。下面是小摘录。如何将宏“mono_atomic_load_acquire”的结果分配给unload_data_unref(..) 中的变量“count”我假设 __tmp 是分配的内容,但我找不到在 C 中以这种方式使用范围界定的任何信息。任何人都可以解释或提供一些有用的链接?

#define mono_atomic_load_acquire(target) ({ \
    typeof (*target) __tmp = *target;   \
    LOAD_ACQUIRE_FENCE; \
    __tmp; })

#define LOAD_ACQUIRE_FENCE MEMORY_BARRIER
#define MEMORY_BARRIER mono_memory_barrier ()

static inline void mono_memory_barrier (void)
{
    // platform specific code
}

unload_data_unref (unload_data *data)
{
    gint32 count;
    do {
        count = mono_atomic_load_acquire (&data->refcount);
        g_assert (count >= 1 && count <= 2);
        if (count == 1) {
            g_free (data);
            return;
        }
    } while (InterlockedCompareExchange (&data->refcount, count, count - 1) != count);
}

【问题讨论】:

  • 我只是没见过这样的东西。它不是一个函数,而是一段代码,其中变量超出了它的范围。它如何返回一个值?
  • 这阻止了我在 Visual Studio 2012 下编译单声道。我将如何在 Visual Studio 中编写它?

标签: c mono


【解决方案1】:

这是一个 GNU 扩展,它们被称为语句表达式(不要与称为“表达式语句”的标准 C 语言结构混淆)。事实上,分配的是__tmpDocs here.

【讨论】:

    【解决方案2】:

    所以这是statement expression。它是gcc extension,根据文档6.1 Statements and Declarations in Expressions

    复合语句的最后应该是一个表达式,后跟一个分号;这个子表达式的值作为整个构造的值。

    在这种情况下,它将是__tmp。根据文档:

    此功能在使宏定义“安全”方面特别有用(因此它们对每个操作数只计算一次)。

    它给出了这个例子,没有使用statement expressions

    #define max(a,b) ((a) > (b) ? (a) : (b))
    

    safe 版本相比,需要注意的是您知道操作数的类型:

    #define maxint(a,b) \
       ({int _a = (a), _b = (b); _a > _b ? _a : _b; })
    

    【讨论】:

      猜你喜欢
      • 2013-11-10
      • 2017-03-11
      • 2016-11-04
      • 2023-04-06
      • 2023-03-03
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多