2011-03-23 41 views
4

通常,在宏中,您會看到人們使用do { ... } while(0)吞下分號。我只是碰到他們使用({ ... })而不是一個例子來,它似乎不僅吞下分號,但似乎讓你返回一個值,以及:在宏中使用({...})括號吞下分號

#define NEW_MACRO() ({ int x = 1; int y = 2; x+y; }) 

if(1) 
    val = NEW_MACRO(); 
else 
    printf("this never prints");` 

VAL會出來爲3,我可以沒有找到任何文件,所以我對此有點謹慎。這個方法有什麼問題嗎?

+0

這是一個GNU擴展。 – 2011-03-23 18:13:24

+0

如果我記得,它不是標準(只有可能gcc兼容)。 – cobbal 2011-03-23 18:13:51

+1

這段代碼不是C,而是「GNU C」。 – 2011-03-23 18:24:31

回答

8

這是無效的標準C.

一些編譯器可能具有擴展名(例如GCC的statement expressions),允許這樣的事情。

+1

這個特殊符號'({...})'被髮明出來了據我所知(至少可以追溯到廣泛使用的GCC 2.7.2.3),並且只有希望與GCC的擴展兼容的編譯器才能找到,比如英特爾專用的Linux編譯器。 – zwol 2011-03-23 18:27:30

+1

+1這也是一種混淆代碼的方式,並且使得調試變得更加困難:) – slezica 2011-03-23 18:27:59

0

do { ... } while(0)不適用於「吞嚥分號」。它用於將C表達式轉換爲C語句。

+2

不,這是爲了將C語言塊變成C語句,這樣它就像一個單獨的「函數調用」,在包含if '/'else'和'do' /'while'語句。 – 2011-03-23 19:55:07

+0

@R它*用於*無論用戶使用它。我已經看到它用於*吞嚥分號,它也有你描述的效果。 – 2017-02-16 17:24:37

1

正如Oli所說的,這是gcc發明的。目標是(通常有typeof擴展名)能夠僅評估一次宏元素,並稍後通過使用名稱使用該計算值。

通過使用inline函數,可以完全避免多次這樣的使用。這些也對(類型)的(非)優勢更加嚴格。

在一些其他情況下,您只需要一個臨時變量的地址您傳遞給函數,C99也有複合文字可用於此。

+0

對於「(dis)」+1和使用複合文字代替醜陋的臨時變量。 – 2011-03-23 19:55:42