初カキコさせていただきます。
WinXPでVC++2005を使っていますが、
複数ステートメントのdefineマクロを
if文と組み合わせて使うと
コンパイルが通らず困っています。
プログラムはこんな感じですが、
#define warizan(a,b); { syou=a/b; amari=a%b; }
void func(void)
{
int syou, amari, a, b;
if (b != 0) warizan(a,b);
else syou = amari = 0;
}
if文とelse文のところで
「';' : 制御が空の文が見つかりました。意図した記述でしょうか?」というワーニング
と
「else 文が if と一致しません。」というコンパイルエラーが出てしまいます。
define定義を「warizan(a,b)」とすればワーニングだけは出なくなるのですが…。
「if (b != 0) warizan(a,b)」とするか、
「if (b != 0) { warizan(a,b); }」とすれば
回避できるにはできるのですが、
いずれもC言語らしくなくなってしまうので…。
何かいい方法はないものでしょうか…?
#define warizan(a,b); { syou=a/b; amari=a%b; }
->
#define warizan(a,b) { syou=a/b; amari=a%b; }
#define warizan(a,b) do{ syou=a/b; amari=a%b; }while(0)
割と良く使われるテクニックです。
参考
http://www.st.rim.or.jp/~phinloda/cqa/cqa8.html#Q10
Kerryさん、ありがとうございます。
こんな方法があったのか。
C言語も、けっこう奥が深いですね。
ぬふやさん、それも試しましたが
コンパイルエラーは解決しませんでした。
今までずっと、「warizan(a,b);」と定義すれば
「;」までが定義内容に置き換わるものと思ってました。
自分もまだまだですね…
#define warizan(a,b) do{ syou=a/b; amari=a%b; }while(0)]
条件式が定数という警告が出る(コンパイラと警告レベル次第)のが
ちょっと悲しいところではありますが、無難な方法ですね。
#define warizan(a,b) { syou=a/b; amari=a%b; }
if (b != 0)
{
warizan(a,b);
}
else
{
syou = amari = 0;
}
> if (b != 0) { warizan(a,b); }
俺はこれが好き。
# 自分で書くなら、{}を省略したりしないので通りすがりさんと多分一緒になります。
> ff (b != 0) { warizan(a,b); }」とすれば
> 回避できるにはできるのですが、
> いずれもC言語らしくなくなってしまうので…。
ちなみに、「むしろむやみに括弧を省略すると危険なので省略しない」という方が
昨今のC/C++の流れ(そしてこれらの派生言語の流れでもある)だと思いますが、
どのあたりにC言語らしさを感じないのでしょうか。
例えば、
「『本物のプログラマ』は冗長な括弧などつけない。
可読性や安全性のためだけの無駄なタイプなど補助輪付きの言語しか知らない臆病者のすること
だ。
『本物のプログラマ』が書くCコードは常に最小のタイプ数になっている」とか、
そういった思想をお持ちで?
括弧の有り無しで議論が発展するとは思わなかった…。
昨今のC/C++の流れは知りませんでしたが
C言語らしくないと言ってしまったのは御幣があったかもしれませんね。
自分のプログラミングスタイルというか、
こだわりのようなものはあるにはありますが、まだ発展途上なんですよ。
今のところ、括弧をつけたりつけなかったり、ケースバイケースで対応しています。
ただ、「if文の処理が一つだけなら括弧を省略できる」というルールがあるなら、
それに一貫したプログラミングをしたいという気持ちはあります。
「普通は省略できるけど、このマクロだけは括弧をつけなきゃならない」
という、例外を生み出したくなかったんです。
>ただ、「if文の処理が一つだけなら括弧を省略できる」というルールがあるな
ら、
>それに一貫したプログラミングをしたいという気持ちはあります。
>「普通は省略できるけど、このマクロだけは括弧をつけなきゃならない」
>という、例外を生み出したくなかったんです。
・一つだけなら括弧を省略する複数なら括弧をつける
より
・常に括弧をつける
の方が表記の上では例外がないように見える気が
私も、んーさんに同意ですね。
一文の時は、省略できると言う部分がむしろ例外的な処理だと思うので
一文だろうが、複数文だろうが中括弧をつけてしまった方が一々判断するよりも
シンプルでわかりやすいと言う事だと思いますね。
単文で済んでいた所にコードを追加して複数文になった時でも
気にする必要がなくなりますしね。
私自身は、逆に必ず中括弧をつける方で統一しています。
私の場合は、「({}は)付ける必要があるときに付ける」ですね。
ただまぁif文がネストする場合とか、文脈によって{}を付けた方が
読みやすくなるような場面では単一文でも付けたりしますが。
ですので「ぱっと見関数のように見えるマクロ」が関数と同じように
記述できなかったら気持ち悪いなぁと思います…
私もKerryさんと同じく、どちらかというと省略したい派です。
「if文の処理が一つだけなら括弧を省略できる」というルールは、
もうすっかり自分の頭の中に染み込んでしまってますから、
そこから外れるほうが自分にとっては例外な気がします。
簡潔な表記ができるのがC言語のいいところだと思ってるので、
そのメリットはやはり最大限活かしたいですね。