2011-10-19 10 views
11

私は最近、このGCCマクロが見つかりました:私はこのコードを見る前`({...})`はどのように値を返しますか?

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

私はあなたが私に与えてもらえ)コード{...}のブロックが何とかC.
1の値を返すことができることを、認識していませんでしたどのようにこのヒント?

けれども、私は通常、カンマ演算子悪用することにより、同じ結果を達成することができました:

#define max(a,b) \ 
    (typeof (a) _a = (a), \ 
    typeof (b) _b = (b), \ 
    (_a > _b ? _a : _b)) 

するか、それが唯一の副作用のためだった場合、私はdo { ... } while(0)

2を使用します)とは何これを行うための好ましい方法ですか?

+1

保護された質問になる可能性があります。多くのC(とC++、私は信じています)プログラマーは '({...})'がGCC拡張であり、C言語の一部ではないことを知りません。私見では。 – Jack

答えて

9

({ ... })は、gcc拡張です。

したがって、typeof演算子です。

マクロMAXは(すべて大文字の従来の使用に注意してください)書くことは十分に簡単です:

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

、それは複数回引数の1つを評価し、あなたはとしてそれを呼び出すべきではありませんたとえば、MAX(x++, y--)です。オールキャップの使用は、機能ではなくマクロであり、副作用を伴う議論に注意することをユーザーに思い出させる役割を果たします。

または、それぞれのタイプに対して関数(おそらくインライン1つ)を書くことができます。

+2

+1うわー: - |、本当に '({...})'について知りませんでした。彼らは完全にそれを言語に入れなければならない。 – cnicutar

+2

['({...})'](http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Statement-Exprs.html#Statement-Exprs)リンクをありがとうございます!句読点だけでGoogleにすることは常に難しいです。 – Halst

10

GCC拡張です。コンマ演算子は動作しません:

// C89, doesn't work... 
#define max(a,b) \ 
    (typeof (a) _a = (a), \ 
    typeof (b) _b = (b), \ 
    (_a > _b ? _a : _b)) 

コンマ演算子は、式だけで動作し、typeof(a) _a = (a);は宣言、ない表現です。 GCCエクステンションやC11のないマクロを書くことは実際にはできません。これは_Genericです。 typeofはGCC拡張ですので、typeofも削除しない限り、({...})を削除しても移植性はありません。

ここではC11バージョンですが、これは比較によってどの程度冗長であるかに注意してください(2つのタイプしか扱えません)。 C11でも幸運はこれをテストするようにコンパイラを見つけようと、まだサポートされていません。

// C11 
static inline int maxi(int x, int y) { return x > y ? x : y; } 
static inline long maxl(long x, long y) { return x > y ? x : y; } 
#define max(x, y) _Generic((x), \ 
    long: maxl(x,y), \ 
    int:_Generic((y), \ 
     int: maxi(x,y), \ 
     long: maxl(x,y))) 

ポータブルC99では、あなたが同様の効果を得ることができるマクロまたはインライン関数で、除くを書くことができますそれだけだろうマクロごとに1つのタイプの作業。 C89/C90で

// C99 
static inline int maxi(int x, int y) { return x > y ? x : y; } 

、私はそれが二回xまたはyを評価しないような方法でマクロを書くためにどのような方法を考えることはできません。

+7

何も言わない答えを書かないでください。ちょうどあなたの時間を過ごし、良い答えを書いてください。それが良い場合、それはupvotesをたくさん得るでしょう。その質問をあなた自身のものとして主張する必要はありません。 –

+0

申し訳ありませんが、私はよく知られていない端末を使用していますので、私が書いたものを失うことはありませんので、ドラフトを保存しようとしています。本当に「自分のものとして質問する」ことを試みているわけではありません。 –

+1

Ok、+1今、優秀な答え –

関連する問題