web-dev-qa-db-ja.com

C ++ 17の__cplusplusの価値は何ですか?

C++ 17およびその std::uncaught_exceptionへの変更 でいくつかのコードをテストしようとしています。 GCCに__cplusplusの値を提供させることはできません。

$ /opt/local/bin/g++ -std=c++17 -dM -E - </dev/null | grep __cplusplus
cc1: warning: command line option '-std=c++1z' is valid for C++/ObjC++ but not for C
$

そして:

$ /opt/local/bin/g++ --version
g++-mp-6 (MacPorts gcc6 6.1.0_0) 6.1.0
Copyright (C) 2016 Free Software Foundation, Inc.

C++ 17を使用する場合の__cplusplusの値は何ですか?

27
jww

C++ 17を使用する場合の__cplusplusの値は何ですか?

ドラフト標準に従って N4594§16.8/p1事前定義されたマクロ名[cpp.predefined] Emphasis Mine) :

次のマクロ名は、実装によって定義されます。__cplusplus名前__cplusplusは、C++翻訳単位をコンパイルするときに値201402Lに定義されます。156

156)この標準の将来のバージョンは、このマクロの値をより大きな値に置き換えることを意図しています。準拠していないコンパイラは、最大で5桁の10進数の値を使用する必要があります。

ただし、C++ 14標準には同じ値が指定されています。どうやら、C++ 17標準にはまだ公式/標準の__cplusplus値が設定されていないようです。

GCCバージョン6.1および7.0では、値は201500に変更されます

ライブデモ

Clangバージョン3.8および3.9では、値は変更されていません201406

したがって、標準値が出るまで少し待つ必要があります。

---更新---

C++標準§19.8/p1によると、事前定義されたマクロ名[cpp.predefined] Emphasis Mine):

1 次のマクロ名は実装によって定義されます:

__cplusplus整数リテラル201703L

したがって、C++ 17を使用する場合の__cplusplusの値は201703Lになります。

34
101010

しようと思います

#if __cplusplus > 201402L
  // C__17 code here
  ...
#endif

言い換えれば、コンパイラーがより多くの機能を追加するので、C++ 14を超えるテストは機能するはずです。前述のように、gccは201500Lを使用します。 clangは201406Lを使用しているようです(C++ 14の4か月後)。

上記の使用はクロスプラットフォームである必要があり、C++ 17が__cplusplusの実際の値を使用する場合でも機能します。進化する機能の詳細については、 機能テストマクロ を試してください。

13
emsr

Gnu C++コンパイラを使用しているものとして引用してこの質問をしたことを理解していますが、Visual C++コンパイラで何が起こるかをある程度知りたいと思うかもしれません、厳密に言えば、あなたの質問は特定のコンパイラについては尋ねませんでした。

現在、この投稿の日付の時点で、VC++ 2017コンパイラは、c ++ 17を使用するようにコンパイラを設定した場合に予想されるものではなく、__cplusplus199711Lに設定します。

正しくレポートするには、/Zc:__cplusplusも設定する必要があります。

(ソース: https://docs.Microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2017

理由は?まあ...彼らの言葉で:

デフォルトでマクロを更新しようとしましたが、__ cplusplusの値を変更すると、多くのコードが正しくコンパイルされないことがわかりました。

(ソース: https://devblogs.Microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/

4

なぜかわからない__cplusplusは通常のマクロとしては表示されませんが、再定義できないためだと思います。これは私がその値を決定する方法です。

#include <iostream>
int main( int argc, char** argv )
{
  std::cout << __cplusplus << std::endl;
  return 0;
}

その後、コンパイルにより値が表示されます。

$ g++-6 test.cpp && ./a.out
201402
$ g++-6 -std=c++17 test.cpp && ./a.out
201500

私はそれが>= 201500特定の値をチェックするのではなく。

3
robert