1

C++ では、一部のコンテキストでは、括弧によって囲まれた式の意味が変わる場合があります (特定のコンテキストに対して)。たとえば、 decltype(expr) と decltype((expr)) はしばしば異なる型を生成します:

int x;
decltype(x) a=x; // type int; a initialized with a copy of x
decltype((x)) b=x;//type int&; b is a reference to  x; extra parentheses matter!

しかし、Cはどうですか?

マクロ パラメーターを括弧で囲むことは、C では一般的な方法ですが、予期しない副作用が発生する可能性はありますか?

[編集] より正確には、括弧がグループ化に冗長である場合、プログラムの意味を変更できますか?

式のみを考慮します (型、関数パラメーター リストなどの他の構文要素は考慮しません)。

4

3 に答える 3

1

答えは「いいえ」だと思います。

((blah))のように、余分な不要な括弧のペアを追加すると意味が変わるというケースは知りません。あなたが言うように、これはほとんどのマクロ定義にとって重要です。

ただし、明示的なグループ化によって、数学の規則に関係のない変更が発生する可能性があるさまざまなケースがあります。私は言及していません(1+2)*3; それはただの数学です。これは、コンパイラーが最終的に異なるが同等のコード シーケンスを生成することを意味します。

たとえば、次の関数を考えてみましょう。

float fourth_power (float n) {
  return n*n*n*n;
}

この関数とは異なる方法で実行できます。

float fourth_power (float n) {
  return (n*n)*(n*n);
}

純粋な数学では結果は同じであるはずですが、実際には有限サイズの float 値を使用すると、異なる数値の答えを得ることができますが、それは私がここで話していることではありません。

私が話している変更点は、2 番目のフォームの実行速度が向上したことです。小さい数値のみを使用していることがわかっている場合 (float の制限が問題にならない場合)、速度を上げるために 2 番目の方法でコーディングすることをお勧めします。

実際、GCC は を使用するとこの変換を行う-ffast-mathと思いますが、通常はコンパイラが安全に処理します。

これはおそらくすべてのコンパイラーに当てはまる例の 1 つですが (数値の正確さに関係するため)、明らかに恣意的なグループ化の決定が特定のコンパイラーを別の内部決定パスに導き、興味深く、測定可能にする例がたくさんあります。パフォーマンス、コードサイズなどの違い。

于 2013-10-30T12:06:09.927 に答える
0

このようなもの?

#define ODD( n ) n % 2

int a = 2;
bool n1 = ODD( a + 1 ); // a + 2 % 2
bool n2 = ODD( (a+1) ); // (a + 2) % 2

n1 true (!=0)
n2 false (==0)
于 2013-10-30T13:07:50.637 に答える