31214


次のようなソースがあります。

test.cpp

[code]

    #include <stdio.h>
    
    int main()
    {
            puts("(???)");
            return 0;
    }
    
[/code]

これを `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 を有効にして、かつトライグラフを無効にする方法はないでしょうか？


CC BY-SA 3.0
2016-12-17T19:49:23.590
31209
2016-12-18T06:14:19.257
3337
question
c++ c++11
C++11でトライグラフを無効にしたい


`-std=c++11` の代わりに `-std=gnu++11` を使えば、トライグラフを無視してくれます。

g++ 独自の機能は使いたくない、純粋な標準に準拠したいということならば、`\`で`?`をエスケープするしかないと思います。

[code]

        puts("(\?\?\?)");
    
[/code]


CC BY-SA 3.0
2016-12-17T21:10:30.030
31210
2016-12-17T21:10:30.030
3605
31209
answer


トライグラフはC++言語仕様の一部であり、GCCのISO C++準拠モード(`-std=c++11`)ではトライグラフを無効化できないようです。

トライグラフを回避するには、(1)`\?`とエスケープするか、(2)文字列リテラルを分割する必要があります。また意図しないトライグラフ変換を避けるため、`-Wall`オプションの指定を強くおすすめします。

[code]

    puts("(??\?)");   // (1)
    puts("(??""?)");  // (2)
    
    puts("(???)");  // "(?]"に変換される
    // warning: trigraph ??) converted to ] [-Wtrigraphs]
    
[/code]

<http://melpon.org/wandbox/permlink/XuW4H0wnBDhHySkd>

おまけ：次期標準C++1z(C++17予定)では[トライグラフが仕様から削除](http://faithandbrave.hateblo.jp/entry/2016/12/05/172553)されます。新しいGCCやClangへのc++1z準拠指定でトライグラフが無効化される理由はこれです。将来的には気にしなくても良くなるでしょう。


CC BY-SA 3.0
2016-12-18T06:09:07.803
31214
2016-12-18T06:14:19.257
2016-12-18T06:14:19.257
49
49
31209
answer