は文の表現です。そのような文の式の結果は、({})
の最後の式の文です。あなたの場合は&__get_cpu_var(var)
になります。
&
演算子は、__get_cpu_var(var)
サブ式の結果に適用されます。つまり、__get_cpu_var
は左辺値を返します。これが確かにCならば、__get_cpu_var
もマクロでなければなりません。なぜなら、C言語関数ではlvaluesを返すことができないからです。
演算子は、上記のマクロ定義の冒頭にある*
演算子によって参照解除されるポインタ(文全体の式の結果)を生成します。したがって、上記のマクロは基本的に*&__get_cpu_var(var)
の式と同等です。
__get_cpu_var(var)
以外にも、*&__get_cpu_var(var)
というように実装されている理由があります。これはルーテンスの結果を__get_cpu_var(var)
に保存するために行われます。文の式の結果は、({})
内の最後のstetementが左辺値だったとしても、常に右辺値になります。結果の有益性を保つために、よく知られている*&
トリックが使用されます。
このトリックは、GCCステートメントの表現に限定されません。これは、通常の日常的なCプログラミングで比較的頻繁に使用されます。たとえば、2つの変数
int a, b;
を持っていて、セレクタ変数select
に応じて、(我々はそれに42
を割り当てたいとしましょう)左辺値としてa
またはb
のいずれかを返す式を書きたいと想像。 C言語で?:
オペレータがそのオペランドのlvaluenessを失うので、これは、動作しません
(select ? a : b) = 42;
を次のように素朴な試みが見えるかもしれません。結果は右辺値になります。右辺値は代入できません。このような状況では*&
トリックは救助
*(select ? &a : &b) = 42;
に来て、意図したように、今では動作します。
元のポスターのマクロ定義には、一見冗長な*
のアプリケーションと&
のアプリケーションが含まれています。そのため、あなたはassgnmentだけ右側にget_cpu_var
を使用することができるだろうというトリックなし
something = get_cpu_var(something);
get_cpu_var(something) = something;
のいずれかの側に上記get_cpu_var
マクロを使用することができます。
C++言語では、参照を使用すると同じ効果が得られます。 Cでは参照がないので、代わりにこのようなトリックを使用します。
出典
2012-04-15 21:35:21
AnT
*(...)は結果の型変換ですか? *編集しました。記入してありがとうございます。 –
これは基本的に '*&__get_cpu_var(var)'を返しますが、なぜ単に '__get_cpu_var(var)'を返さないのですか?コンパイル時の型チェックのいくつかの種類? – Anthales
@Anthales:私は答えを上記に加えました – AnT