2013-07-01 47 views
6

我偶然發現了一些看似不合理的代碼,但顯然是因爲它坐在Mono codebase for already 2 years中。下面是小節選。如何將宏「mono_atomic_load_acquire」的結果分配給unload_data_unref(..)中的變量「count」我假設__tmp是正在分配的內容,但是我找不到任何有關在C中使用此方法範圍的信息。是否有人可以解釋或給一些有用的鏈接?從範圍塊中分配了返回值的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); 
} 
+0

我只是還沒有看到類似的東西。這不是一個函數,而是一個代碼塊,其中的變量超出了範圍。它如何返回一個值? – voldemarz

+0

這阻止了我在Visual Studio 2012下編譯單聲道。如何在Visual Studio中編寫它? –

回答

5

這是一個GNU擴展,它們被稱爲語句表達式(不要與稱爲「表達式語句」的標準C語言結構混淆)。事實上,它是__tmp分配。 Docs here.

0

所以這是一個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; })