3

私はEffectiveC++を読み始めましたが、項目2のある時点で、次のことが言及されています。

// call f with the maximum of a and b
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))

...

int a = 5, b = 0;
CALL_WITH_MAX(++a, b); // a is incremented twice
CALL_WITH_MAX(++a, b+10); // a is incremented once

ここで、fを呼び出す前にaがインクリメントされる回数は、比較対象によって異なります。

確かに、で単純な印刷ステートメントを使用するfと、最初の呼び出しで7が印刷されますが、私は一生の間、その理由を理解できません。明らかな何かが欠けていますか?

4

2 に答える 2

5

コンパイラは、マクロをそのまま渡したものに置き換えます。だからあなたは

int a = 5, b = 0;
f((++a) > (b) ? (++a) : (b));
f((++a) > (b+10) ? (++a) : (b+10));
于 2013-02-22T23:12:58.247 に答える
1

使用(使用していない場合はにg++ -E myprog.cpp置き換えます)-ほとんどすべてのコンパイラで動作し、前処理後に実際のものを生成します。g++whatever-your-compiler-isg++

そしてこれは、関数型の処理を行うためにマクロを使用すべきでない理由の良い例です。

インライン関数を使用すると、(おそらく)期待するものがはるかに多くなります。

 inline void CallWithMax(int a, int b) 
 {
     f((a) > (b) ? (a) : (b));
 }

適切なコンパイラは、少なくともマクロと同じくらい効率的にこれを実行できるはずです。さらに、呼び出し元のコードでとが一度評価され、「奇妙な」ことは何も起こらないという利点がありaますb

デバッグシンボルを使用してコードをビルドする場合は、インライン関数をステップ実行することもできます。したがって、関数内に実際にどのような値があるかを確認したい場合は、それを実行できますabマクロは、ソースコードの元の場所に展開されるため、内部で何が起こっているのかを実際に確認することはできません。

于 2013-02-22T23:20:43.430 に答える