5

Linux Device Drivers 3rd Edition book をオンラインで読んでいますが、アトミック変数の初期化マクロを理解するのに問題があります。

static atomic_t foobar = ATOMIC_INIT(1);

Linux カーネル v3.2のソース コードを調べましたが、次の2 つの定義しか思いつきませんでした。

#define ATOMIC_INIT(i) { (i) }

#define ATOMIC_INIT(i) ((atomic_t) { (i) })

マクロの定義の 2 番目のバージョンは、機能的には最初のものと同じようですatomic_t。定義に 2 つのバージョンがあるのはなぜですか?

マクロの目的は、Linux カーネルの将来のリリースで構造が変更されたATOMIC_INIT場合にコードが壊れないようにすることだけですか?atomic_t

4

2 に答える 2

2

の 2 つの異なる形式の違いはATOMIC_INIT、最初の形式は初期化でのみ使用でき、2 番目の形式は初期化と代入で使用できることです。一見すると、これは 2 番目の方法が望ましいように思えますが、適用できない重要なユース ケースがあります。それは、staticストレージ仕様で宣言されたブロック スコープ変数です。ブロックスコープ内

static atomic_t foobar = ((atomic_t) { (1) });

初期化子はコンパイル時の定数式ではないため、標準 C では無効です。(ファイルスコープでは、複合リテラルは静的に割り当てられるため、そこで機能します。)

gccにはそのようなコードを許可する拡張機能があり、これがC99に移行せず、C方言としてgnu89に固執する理由の1つであると述べたカーネルリストに関する議論を漠然と覚えています。

于 2013-04-25T15:18:42.933 に答える