忍者ブログ
C言語のマクロについてです。C言語のマクロには落とし穴が多いので、マクロをマスターして引っかからないようにしましょう。そしてC言語の達人になってください。
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

C言語のマクロはテキスト置換ですので、
気をつけていないと、
思わぬ不具合に見舞われます。

一番簡単な例を見てみましょう。

#define VOLUME 90 + 10

プログラム中で次の計算をしたとします。

y = x * VOLUME;

プログラムを書いた人は、

x * 100

を計算したかったと思われます。
しかし、実際には下記のように展開されます。

y = x * 90 + 10

これは、プログラムを書いた人の意図と
違うと思われます。

この問題は下記のようにすれば回避できます。

#define VOLUME (90 + 10)

この場合、

y = x * (90 + 10)

と展開されますので、
意図したとおりの計算結果となります。

C言語のマクロの置換字句は、
全体を括弧で括ったほうがよいでしょう。
PR
関数マクロにも、注意すべき点があります。

次の例を見てみましょう。

#define CIRCUMFERENCE(r) (2 * r * 3.14)

円周を求めるマクロですが、

c = CIRCUMFERENCE(10 + 5);

という使われ方をすると、
下記のように展開され、
円周が計算されません。

c = (2 * 10 + 5 * 3.14);

本来なら、次のように
展開されて欲しかったはずです。

c = (2 * (10 + 5) * 3.14);

C言語の関数マクロの引数は、下記のように
括弧で括ったほうがよいでしょう。

#define CIRCUMFERENCE(r) (2 * (r) * 3.14)
C言語マクロの大きな注意点に
副作用の問題があります。

#define MAX(a,b) ((a) > (b) ? (a) : (b))

上記のマクロを次のように使用したとします。

m = MAX(++a, --b);

コーディングした人の意図は、
aをインクリメントした値と
bをデクリメントした値の大きい方を
mに代入する、だと思われます。

しかし、マクロの展開結果は次のようになります。

m = ((++a) > (--b) ? (++a) : (--b))

大小の比較時に引数のインクリメント、
デクリメントが行われ、さらに、
結果を返す時にインクリメントまたは
デクリメントが行われてしまいます。

これは、明らかにコーディングした人の
意図と異なります。

C言語の関数形式マクロの引数には、
インクリメント、デクリメント等の
演算子を含んだ式を渡さない方がよいでしょう。
HOMENext ≫
ブログ内検索
バーコード
アーカイブ

Copyright © [ C言語のマクロ ] All rights reserved.
Special Template : 忍者ブログ de テンプレート
Special Thanks : 忍者ブログ
Commercial message : [PR]