コンパイラが使用するC ++標準のバージョンを確認する方法は?


114

コンパイラーによって実装されているC ++標準のバージョンをどのように判断しますか?私が知る限り、以下は私が知っている標準です:

  • C ++ 03
  • C ++ 98

3
このc ++にタグを付けましたが、リストした3つの標準のうち2つはC ++標準ではありません。どの言語に興味がありますか?
Rob Kennedy、

1
そして、質問はほんの数分前に尋ねられました。(stackoverflow.com/questions/7132440/...
マット

1
@マット:質問がゴミであり、それに他の恣意的なナンセンスなピギーバックがあったため、ポーズをとってクローズしました。まともな形で再投稿しました。オリジナルが修正されて復活すると思われる場合は、こちらを閉じていただければ幸いですが、息を止めていません。
軌道の軽さのレース2011年

1
@マット:ええと、最良の答えはコンパイラの静的なリストではなく、何が使用されているかを自分で判断する方法です。さあ、行きます。
オービットでのライトネスレース

1
@アルス:もうすぐです。約束します。その上、c++-faqタグには、渡す必要のある実際の前提条件の「要求された回数」はありません。それはもののフォーマットと一般性についてです。
軌道の軽さのレース

回答:


13

私の知識では、これを行うための全体的な方法はありません。クロスプラットフォーム/マルチコンパイラサポートライブラリのヘッダーを見ると、コンパイラ固有の構成を使用してそのようなことを決定する多くの定義が常に見つかります。

/*Define Microsoft Visual C++ .NET (32-bit) compiler */
#if (defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER >= 1300)
     ...
#endif

/*Define Borland 5.0 C++ (16-bit) compiler */
#if defined(__BORLANDC__) && !defined(__WIN32__)
     ...
#endif

おそらく、使用するすべてのコンパイラーに対して、このような定義を自分で行う必要があります。


1
私の期待する答えではありませんが、それを見つける普遍的な方法はないと思います。
jasonline 2010

246

Bjarne Stroustrup C ++ 0x FAQから

__cplusplus

C ++ 0xでは、マクロ__cplusplusは現在のとは異なる(より大きい)値に設定されます199711L

これは希望するほど役に立ちませんが。gcc(どうやら10年近く)この値はに設定され1gcc 4.7.0がリリースされたときに修正されるまで、主要なコンパイラを1つ除外していました

これらはC ++標準であり、期待できる値は__cplusplus次のとおりです。

  • C ++ pre-C ++ 98:__cplusplusです1
  • C ++ 98:__cplusplusです199711L
  • C ++ 98 + TR1:これはC ++ 98として読み取り、私が知っていることを確認する方法はありません。
  • C ++ 11:__cplusplusです201103L
  • C ++ 14:__cplusplusです201402L
  • C ++ 17:__cplusplusです201703L

コンパイラが古い可能性がある場合は、コンパイラgcc固有のハッカー(バージョンマクロを確認し、実装された機能を備えたテーブルと比較する)に頼るか、Boost.Config関連するマクロを提供する)を使用する必要があります。これの利点は、新しい標準の特定の機能を実際に選択して、その機能がない場合の回避策を記述できることです。一部のコンパイラはC ++ 11の実装を要求するが、機能のサブセットしか提供しないため、これはホールセールソリューションよりも多くの場合推奨されます。

Stdcxx Wikiは、コンパイラーがC ++ 0x機能をサポートするための包括的なマトリックスをホストしています(機能を自分で確認する場合)。

残念ながら、より細かくグレイン(のような例えば、個々のライブラリ関数の機能をチェックするstd::copy_if-それがコンパイルされ、正しい結果が得られている場合)は、アプリケーションのビルドシステムでのみを行うことができます(機能と、実行コード、チェックautoconf取った場合、選択したツールです。このルート)。


コンパイラベンダーがこれを更新しているようではありません。おそらく標準に完全に準拠するまで待っているのでしょうか?(stackoverflow.com/q/14131454/11698
Richard Corden

2
@prnr:それは本当かもしれませんが、どの回答を受け入れるかを決定するために質問をしたユーザー次第です。採点済みの回答が投稿された時点では正解だったため、元の投稿者が採択しました。そのユーザーは、承認された回答を変更することを決定できますが、サイトでアクティブでなくなっている可能性があります。参照:meta.stackexchange.com/questions/120568/...
ダン・コーン

3
vs2017は__cplusplusの値199711
Al

5
@AlMamun Microsoft __cplusplusはVS 15.7でのみ部分的に修正されました。その参照のVisual C ++チームのブログ
Ivan_Bereziuk

1
FAQへのリンクが壊れています。
ブレインプロット

38

次のコードを実行してバージョンを確認してください。

#include<iostream>

int main() {
    if (__cplusplus == 201703L) std::cout << "C++17\n";
    else if (__cplusplus == 201402L) std::cout << "C++14\n";
    else if (__cplusplus == 201103L) std::cout << "C++11\n";
    else if (__cplusplus == 199711L) std::cout << "C++98\n";
    else std::cout << "pre-standard C++\n";
}

8
面白いのは、ビジュアルスタジオでは__cplusplusの値が199711Lで、投稿したコードがc ++ 98を返したためですが、変数テンプレートやdecltype(auto)など、c ++ 14の機能を使用しました。間違ったバージョンのマクロが実装された可能性はありますか?
コリンヒックス

2
参照:devblogs.microsoft.com/cppblog/…(TLDR:フラグを指定してください/Zc:__cplusplus
Daan Timmer

@DaanTimmerその記事に戸惑っていますが、/Zc:__cplusplusフラグの使い方を知っていると思われます。もちろんstd::cout << /Zc:__cplusplus;、コロンとスラッシュを変数名の一部にすることはできないからです。これを行う方法を説明できますか?ありがとう。
A__


7

達成したいことによっては、Boost.Configが役立つ場合があります。標準バージョンの検出は提供しませんが、特定の言語/コンパイラ機能のサポートを確認できるマクロを提供します。


3
とにかく、標準バージョンをチェックするよりも、機能をチェックする方が良いでしょう。標準からのすべてをサポートするコンパイラはほとんどありませんが、必要な機能の数が限られている場合は、特定の標準の残りの機能が実装され、正しく機能しているかどうかは問題ではありません。
ロブ・ケネディ



0

簡単なグーグルの後:

__STDC__そして__STDC_VERSION__こちらをご覧ください


__STDC__定義されているかどうか、およびその値はC ++で実装定義されています。
ロブ・ケネディ

@ロブ:はい、そうです。@Tor:私はVC ++ 2005で試しましたが、STDCは宣言されていない識別子であると言っています。ただし、これらの定義済みマクロの1つとしてリストされています。ただし、STDC_VERSIONは存在しません。
jasonline 2010

これにより、コンパイラでサポートされているCプログラミング言語のバージョンがわかります。サポートされているC ++言語のバージョンについては何もわかりません。
ダンモールディング

0

通常は、__cplusplusdefineを使用してc ++ 17を検出する必要がありますが、デフォルトでは、Microsoftコンパイラーはそのマクロを適切に定義していません。https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/を参照してください -必要ですプロジェクト設定を変更して/Zc:__cplusplusスイッチを含めるか、次のような構文を使用できます。

#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
     //C++17 specific stuff here
#endif
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.