GCC拡張の無効化 (と、それにまつわる細かい話)
端的に言えば-pedantic-errors
を使えばよい。(できれば-std=...
も併用したほうがいいだろう)
以下解説
GCCのC/C++コンパイラは、独自の拡張機能を導入している。これを無効化するオプションには2種類あり、意味が異なる。
実は、C言語の規格は、それぞれのコンパイラの拡張機能を全面的に禁止しているわけではない。「正しいプログラム(strictly conforming program)を正しく動かす」ことさえ満たせばいいので、いくつかの拡張機能が有効化されたままでも、標準に準拠していると言える場合があるのだ。
C標準と矛盾する拡張機能を無効化する
C標準と矛盾する拡張機能を無効化するには、 -std
オプションでISO C/C++を指定すればいい。 C Dialect Options - Using the GNU Compiler Collection (GCC) このオプションは、「C/C++のバージョン」「ISO準拠またはGNU独自」の2つの内容を指定する。
このオプションのデフォルトは、-std=gnu11
や-std=gnu++03
のように、gnuが含まれている設定である。これには、C標準と矛盾する拡張機能が含まれている。これを-std=c11
や-std=c++14
のように、cが含まれている設定に変えれば、C標準に準拠した挙動になる。
C標準と矛盾する拡張機能の例
- 1行コメント : C89と矛盾する。一見矛盾しないように見えるが、1行コメントの有無により挙動が変わるコードが存在する。
- Trigraphの無効化 :
"??/"
のようなコードの解釈が変わる。 typeof
: C++11以降のdecltype
に相当する機能。このような予約語をC標準の範囲内で追加することはできない(変数名と衝突する可能性があるからである)。同じ機能をもつ__typeof__
は問題ない。
多くのGCC拡張機能は、既存のCコードの意味を変えないように配慮されている。したがって、この方法で拡張機能を無効化することによる影響はそれほど大きくはない。
拡張機能を無効化する/または警告を出す
- 拡張機能に警告を出すには、
-Wpedantic
オプション*1を使う。 C Dialect Options - Using the GNU Compiler Collection (GCC) - 拡張機能をエラーにするには、
-pedantic-errors
オプションを使う。
これは、C/C++コード中で拡張機能が利用されていた時に、警告またはエラーにする機能である。
このオプションの挙動も明快に説明できるわけではなく、色々な注釈が必要である。
long long
など、「以前のバージョンではGCC拡張であったが、新しいバージョンでは標準」という機能は多数存在する。これらは、-std=c...
で指定されたバージョンに応じて判定する。-std=gnu...
が指定されていた場合は、対応するISO C/C++標準に基づいて判定する。しかし、-pedantic-errors
を指定していても、例えば-std=c90
と-std=gnu90
では意味が違う。上記の1行コメントの例は、前者ではコンパイルが通るが、後者ではコンパイルエラーになる。-Werror=pedantic
とすると、-Wpedantic
で出る警告すべてをエラーにすることができる。これは-pedantic-errors
とは微妙に意味が異なる。*2- 明示的に「拡張機能」とされているものを判定することはできるが、これによってプログラムが本当の意味でISO C/C++準拠であるかを確認できるとは限らない。