2013年2月25日月曜日

-pedanticまたは/Zaを基本的には常用しよう

前略でしへ。

GCCで必要最小限C++11ソースを実行バイナリーへする方法

`g++ -std=c++11 source.cxx`

で良い。

しかしこれは普段使うには、またC++を学習し始めた様な段階で使うのは危険だ。この方法では例えば次の様なコードが意図せずとも翻訳できてしまう。

int main(int ac, char** avs) { return ac ? : -1; }

このコードの問題は ? と : の間にスペースしかない事だ。本来ならばここには ? の手前の項が true となる場合に採用される値を示す項が存在しなければ翻訳できずエラーとなるはずであったが実際エラーどころか警告も出ない

この様なコードはC++言語規格では対応していない。これらはC++という言語の設計を元に実装された1つのコンパイラーとしてのGCCが独自に拡張した言語仕様による(参考)。ソースコードの移植性や保守性、また意図しない使用によるバグ避ける為にも通常は使わない方が良い。

しかし言語仕様と実装拡張仕様を脳内に完全に修めて注意深くコードを書くという解決方法は非現実的である。ではどうしたら良いか?

`g++ -std=c++11 -pedantic source.cxx`

と、オプションを1つ追加するだけで解決できる。これだけで先に紹介したコードは警告を発するようになる。警告では無くエラーにして構わなければ`-pedantic-errors`とすれば望みが叶う。
MSVC++にも多くの独自拡張仕様がある。GCCの例と同様に実装独自の拡張仕様を無効化するには翻訳時のオプションに`/Za`を加えれば良いらしい。
C++にも、使うべき実装にも熟知し、作ろうとするプログラムの設計や用途や保守について十分な理由があり決断できるの訳で無ければこれらのオプションは忘れずに常に付ける様にした方が懸命だろう。

また、GCCやClangでは`-Wall`、MSVC++では`/Wall`も併用して、警告を1つたりとも受けないソースコードを常に書けるように意識する事はC++界の先人達たちの教えにも良く登場する。もののついでとなったが併せて紹介とする。

0 件のコメント:

コメントを投稿