関数のオーバーロードと糞コード

2015年10月9日 0 投稿者: khws4v1

大学の演習でとんでもない糞コードが出てきてしまったので投稿です。

このコードは学生が書いたものではなく、教員が書いたコードです。

まず、マジックナンバーをガンガン使うコードを平気で推奨するのもそれなりに問題なんですが、それ以上に問題なのが、fabs180.0です。
整数と整数は+しても-しても*しても実数が必要になることはあり得ないので、実数の絶対値を求めるfabs関数を使う理由がさっぱり分かりません。
また、180.0のように無理やり実数にして辻褄を合わせるのも意味不明です。
というか<で比較する対象が整数だし、もう分けわかんねえ。

180.0の理由

実は最初は180.0の部分は普通に180と整数で書いてありました。
では、なぜ180.0と実数にしたのか?
結論を言うとコンパイルエラーになるからなのですが、試しにfabs関数に整数を入れて試してみました。

これをC言語としてコンパイルすれば、コンパイルできます。
fabs関数の引数はdoubleですが、intdoubleに暗黙のキャストがされるからです。

今度はこれをC++としてコンパイルしてみます。
すると、コンパイルエラーになります。

cmp

C言語のヘッダなのに関数のオーバーロードがされているところ自体「は?」って感じですがそれは置いといて。
C++は引数の型や数が異なれば同じ名前の関数を多重定義(オーバーロード)できるので、どうやらMSVC++2010のfabs関数は

long double fabs(long double)

float fabs(float)

double fabs(double)

の少なくとも3つが定義されているみたいです。

intlong doubleにもfloatにもdoubleにも暗黙のキャストが可能です。
となると、一体どの型にキャストしてどの関数を呼べばいいのかはっきりしないので、コンパイルエラーになります。

ではどうすればいいのか、教員がやったみたいに180.0と小数点を加えるとdoubleの実数になります。
double * intdoubleになり、型がはっきりするので、コンパイルできます。
めでたしめでたし。

書くべきだったコード

整数ならabs関数を使う、普通!

まとめ

とりあえず、大学側は

  • C言語とC++をごちゃ混ぜにしない
  • 学生にC言語のソースコードをC++としてコンパイルさせる習慣をやめさせる
  • 整数の絶対値求めたいならfabs関数じゃなくてabs関数を使う

ということをすぐにやってもらったほうがいいですね。