SSブログ

コンパイル時のワーニング(-Wallと-Werror) [プログラマー現役続行]

プログラマー”まだまだ”現役続行 (技評SE選書)

プログラマー”まだまだ”現役続行 (技評SE選書)

  • 作者: 柴田 芳樹
  • 出版社/メーカー: 技術評論社
  • 発売日: 2010/09/04
  • メディア: 単行本(ソフトカバー)

コンパイル時にワーニングを取り除くことについて、拙著の第10章「コードレビューの勧め」の「コードレビューの準備」(p.208)では、次のように述べています。
 実際に何らかの仕様に従ってコーディングを行った後にコードをレビューするのですが、まず作成者がしなければならない作業は、それがクリーンなソースコードであるかどうかを確認することです。
 クリーンなソースコードとは、以下の両方を達成しているコードを指します。
  • コンパイルエラーがないこと
  • ワーニングが出ないこと
 コンパイルエラーがないことは当然としても、ワーニングが出ないことがなぜ必要なのでしょうか?
 自分で最初から書いたコードをコンパイルした際に、コンパイラがワーニングメッセージを出した場合、そのワーニングメッセージを無視してもよいかどうかを判断することは容易です。なぜなら、自分で書いたコードだからです。
 しかし、他人が書いたコードのバグの修正とか、あるいは機能の追加などの作業を行う場合には、そうはいきません。もともとのコードが、コンパイルしただけでワーニングがたくさん表示される場合、自分が修正したことによって新たにワーニングが追加されていたとしても、両者を区別することは容易ではありません。その結果、ワーニングを無視してしまうようになったりします。
 したがって、将来の保守性を考慮すれば、ワーニングが出ないようにコードを作成しておくべきなのです。それをプロジェクトで徹底させるには、gccやg++などのコンパイルオプションで、-Wallを標準として、-Werrorも標準として使用することです。-Wallですべてのワーニング検出が有効になりますし、-Werrorにより、ワーニングがコンパイルエラー扱いとなり、コンパイルできなくなります。その結果として、ワーニングが出力されないソースコードを作成することを、プロジェクトで徹底することが可能となります。
『プログラマー”まだまだ”現役続行』(p.208)
最後の太字にしている段落部分は、初版では書いておらず、改訂版で追記した部分です。私にとっては、-Wallおよび-Werrorをデフォルトのコンパイルオプションに指定して、ソフトウェア開発を行うのが当然だし、長年そうしてきたプロジェクトに従事していたため、常識的な部分だったと思っていました。しかし、実際はあまり行われていないのではないかと思い追記した部分です。

さらに、最近のコンパイラは、単なる言語上の問題だけでなく、printf関数の書式と引数の型のチェックまで行って警告を出してくれます。そのため、コンパイル時に問題となる可能性の箇所をワーニングとして通知してもらい、その場でコンパイルエラー扱いでコンパイルが終わってしまうことが、後で実際に動作させて不具合が発生してから調査するより、非常に簡単だったりします。

これは、開発しようとしているソフトウェアのアーキテクチャとか開発プロセスとは全く別のソフトウェア開発の側面なのです。しかし、この基本的なことさえきちんとできないようであれば、そのソフトウェア開発は着実に技術的負債を積み上げていくことになります。

nice!(1)  コメント(4)  トラックバック(0) 

nice! 1

コメント 4

些細なことですが

ワーニングではなく「ウォーンニング」では?
by 些細なことですが (2011-06-01 21:12) 

たーとる

多数のWarningが出るコードをメンテナンスしていますが、なぜ他の開発者がそれをそのままにしているのはとても不思議です。
いつも出力されるWarningの中に新たなしかもバグの原因にもなりかねないWarningが増えていてもまったく気づかないというヒヤヒヤした経験が何度もあります。

もちろん自分が管理しているコードではWarningは出さないようにする、という大前提を設けています。
by たーとる (2011-06-04 21:45) 

きょうかいな

ボケ防止でC++をいじっている素人です。
g++ で -Wall -Wextra -pedantic -Weffc++ -std=c++?? および、警告して欲しいオプションをいろいろ付けて警告が出ないようにしているのですが。
自作のイテレータを作ってみようか、と std::iterator をpublic継承したところ -Weffc++ から「基底クラスに仮想でないデストラクタがある」と叱られました。
もちろん、オプションで選択的に特定の警告をエラーにするかしないかを指定できますが。この警告をエラーにすべきかどうか頭を悩ませています。

もっとも私は、警告を抑制することなく警告もエラーもなしにしたいので、std::iterator をpublic継承せずにイテレータを作りました。お陰で勉強にはなりましたが。



by きょうかいな (2017-07-14 17:34) 

きょうかいな

std::iterator<・・・> を継承したイテレータにpublicなコンストラクタがあると、new して std::iterator<・・・>* 型にアップキャストしてdeleteして未定義動作という危険な使い方が可能なので、このような危険な使い方がされないように設計されたクラスしか作らない、という条件なら public 継承してもよい筈。
従って、-Weffc++ の警告を常にエラーにすることは疑問。
あるいは #pragma で警告抑制(自分のg++では可能な筈なのにうまく動かない)して「わざとやってる」ことを明記するべきかもしれませんね。
by きょうかいな (2017-07-15 20:57) 

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Facebook コメント

トラックバック 0