質問: 次のようなソースがあります。 test.cpp ``` #include int main() { puts("(???)"); return 0; } ``` これを `g++ test.cpp` の様にコンパイルすると、実行結果は期待通りです。 しかし `g++ -std=c++11 test.cpp` とすると、`(???)`が`(?]`になってしまいます。 `clang++ -std=c++1z test.cpp` なら、期待通りに動作しますが、 Debian (jessie) の g++ 4.9.2 では `c++1z` を指定することができません。 Ubuntu (16.04) の g++ 5.4.0 では `c++1z` は指定でき、期待通りの動作です。 g++ 4.9.2 で c++11 を有効にして、かつトライグラフを無効にする方法はないでしょうか?
回答: トライグラフはC++言語仕様の一部であり、GCCのISO C++準拠モード(`-std=c++11`)ではトライグラフを無効化できないようです。 トライグラフを回避するには、(1)`\?`とエスケープするか、(2)文字列リテラルを分割する必要があります。また意図しないトライグラフ変換を避けるため、`-Wall`オプションの指定を強くおすすめします。 ``` puts("(??\?)"); // (1) puts("(??""?)"); // (2) puts("(???)"); // "(?]"に変換される // warning: trigraph ??) converted to ] [-Wtrigraphs] ``` おまけ:次期標準C++1z(C++17予定)ではトライグラフが仕様から削除されます。新しいGCCやClangへのc++1z準拠指定でトライグラフが無効化される理由はこれです。将来的には気にしなくても良くなるでしょう。