いろんな条件でコンパイルしたほうがよい101の理由

最適化オプションをつけないでコンパイル、ビルドするおもちゃのコードであれば、別にどーでもいいのであるが、通常のソフトウェアであればデフォルトで-O2はつけていると思うので、わざわざ外す必要はない。

デバッグのためだけに最適化オプションを付けないという立場も考えられる。これも悪手である。

その立場の場合、最適化オプション付きのバイナリと最適化オプションなしのバイナリの2種類のバイナリを維持管理する必要がでてくる。

管理すべき実体が増えることは管理のコストが増加して、よろしくない。最適化オプションなしのバイナリで延々デバッグしていたのだが、実は最適化オプションありのバイナリでは当該バグに遭遇しないとか、そもそも、同じソースからコンパイル、ビルドしたのかをどう管理するのかとか、様々なコストが発生する。

マーフィーの法則のとおり、状況は最悪の方向にころがるのである。最適化オプションなしのバイナリはちゃんとデバッグしたんだけど、最適化オプション付きのバイナリは一世代前のバイナリで、バグ付きのまま出荷しちゃったよ、とか悪夢は列挙のいとまがない。

2つバイナリを用意すれば間違いなくテストの工数は2倍になるし、管理のコストも増大する。

2008-09-27 - 未来のいつか/hyoshiokの日記

「一つのソースコードに一つのバイナリ」はシンプルでよい。いわゆるKISSというやつだろうか。
しかし「一つのソースコードから複数のバイナリ」というのもまたよくある話。ビルドオプションを変えたり、別プラットフォームでビルドすると色んなバイナリができるわけだが、そうするメリットを101個挙げてみる。

(0)コードの汎用性が高まる

特定のコンパイラやライブラリではビルドできない部分をつぶすことにより、汎用的なコードになる。

(1)カバレッジ範囲が広がる

あるプラットフォームだけでしか発生しないバグなども検証できる。

(10)たまたま動いているのかどうかがわかる

DEBUGビルドでしか動かない(あるいはその逆)というようなケースから、あやふやな部分が明らかになることがある。

(11)期待した最適化の効果が出ているのかどうかが確かめられる

GCCにも-O3や-Osがあるし、Intelコンパイラなんかだと最適化オプションだらけだったりする。
なし・ゆるい最適化・アグレッシブな最適化、それぞれでビルドしてサイズを比較したり負荷試験したりすれば、最適化の効果がわかる。

(100)プラットフォームが正しく動作しているかどうかが確かめられる

組み込み(特にあまり普及していないプラットフォーム)だとコンパイラやライブラリのバグは珍しくない。ある程度の規模のプログラムは、そのプラットフォーム自体のテストにも使える。


それと、「2つバイナリを用意すれば間違いなくテストの工数は2倍になる」はダウト。
ある程度以上の規模になってくると、レポジトリからチェックアウト→ビルド→指定した位置に格納→レグレッションテストくらいまでは自動でするはず。なので理想的な条件下ではリニアには増えない。
一世代前のバイナリの件も、普通はバージョンやビルド条件をプログラムに格納しておくので、管理上の不手際で一世代前のバイナリを出荷することはあっても、すぐわかる。