GNU/Linux >> Linux の 問題 >  >> Linux

Linux カーネル 2.6.26 で、#define atom_read(v) ((v)->counter + 0) が見つかりました。なぜ +0 なのですか?

+ 0 の場合 使用されていない場合、偶然に割り当てられる可能性のある左辺値、つまり

になります。
if (atomic_read(v) = 42) {
    ...
}

「動作」します... + 0 の代わりに 単項 + を使用できます 、つまり

(+(v)->counter)

ただし + 0 1 あります + よりも優れたアドバンテージ 一般的な場合:+ 引数は算術型である必要があります - ただし、ポインターは算術型ではありません。まだ + 0 ポインターに対しても同様に機能します(ポインターのみの場合は、 &* を使用できます 左辺値を式の値に変換します。これは、null ポインターに対しても機能することが保証されています)


+ 0 の可能性があります 関数のようなマクロの再定義があった場合にコンパイラが診断を発行するために追加されました atomic_read そして atomic64_read .

C 標準に従って、2 番目の定義が同じ数と同じパラメーターのスペルを持つ関数のようなマクロであり、2 つの置換リストが同一である場合、関数のようなマクロである識別子を再定義することが可能です。

C11 標準 (n1570)、セクション 6.10.3/2 から:

<ブロック引用>

... 同様に、関数のようなマクロとして現在定義されている識別子は、別の #define によって再定義されるべきではありません ただし、2 番目の定義が関数のようなマクロ定義であり、パラメーターの数とスペルが同じであり、2 つの置換リストが同一である場合を除きます。

カーネルのバージョン (2.6.26) はかなり古いですが、そのような再定義に対する同様の禁止事項は、C89 標準までの古い標準で見つけることができます。

現在マクロ atomic_readatomic64_read ファイル atomic.h で定義されています .

ユーザーが以下のようにソース ファイルでそれらを再定義する場合:

#define atomic_read(v)      (v)->counter 

コンパイラは、再定義に関する診断を発行します。 + 0 があるため、この警告が発行されます 定義 atomic_readatomic.h の ファイル。

+ 0 がなかったら 、コンパイラは診断を発行しませんでした.

この問題を示す最小限の例:

//atomic.h
#define atomic_read(v)      ((v)->counter + 0)
#define atomic64_read(v)    ((v)->counter)

//some source file that includes atomic.h
#define atomic_read(v)      ((v)->counter) //redefinition error 
#define atomic64_read(v)    ((v)->counter) //no redefinition error 

デモを見る


結果が左辺値になるのを防ぐため、誤って割り当てたり、そのアドレスを取得したりすることはできません。


Linux
  1. Linux –カーネル:名前空間のサポート?

  2. Linux –カーネルIP転送?

  3. Linux – Linuxの汚染されたカーネル?

  1. Linux –ユーザースペースを決して壊さないLinuxカーネルポリシーがあるのはなぜですか?

  2. Linux –カーネルがInitを実行できないのはなぜですか?

  3. Linux –異なるLinux / UNIXカーネルは交換可能ですか?

  1. C プリプロセッサが linux という単語を定数 1 と解釈するのはなぜですか?

  2. Linux カーネルの pr_debug が何も出力しないのはなぜですか?

  3. Linux でシステム コール テーブルを変更する必要があるのはなぜですか?