web-dev-qa-db-ja.com

CPUアーキテクチャのコンパイル時の検出

CまたはC++コードをコンパイルするときにCPUアーキテクチャを見つける最も信頼できる方法は何ですか?私が知る限り、異なるコンパイラは独自の非標準プリプロセッサ定義のセットを持っています(_M_X86 MSVSでは、__i386____arm__ GCCなど)。

私が構築しているアーキテクチャを検出する標準の方法はありますか?そうでない場合、すべてのボイラープレート#ifdefs?

76
Alex B

事前定義されたアーキテクチャマクロ およびその他の事前定義されたマクロに関する情報を次に示します。

この質問 それらが定義されている場所を尋ねる GCCソースコード。

72
Serge

コンパイラー間標準はありませんが、各コンパイラーはかなり一貫している傾向があります。次のようなヘッダーを自分で作成できます。

#if MSVC
#ifdef _M_X86
#define Arch_X86
#endif
#endif

#if GCC
#ifdef __i386__
#define Arch_X86
#endif
#endif

数千のコンパイラがありますが、広範囲に使用されているのは3〜4のみであるため(Microsoft C++、GCC、Intel CC、TenDRAなど)、包括的なリストにはあまり意味がありません。アプリケーションがサポートするコンパイラを決定し、#definesをリストし、必要に応じてヘッダーを更新するだけです。

15
John Millikin

特定のプラットフォームで利用可能なすべての機能をダンプする場合は、次のようにGCCを実行できます。

gcc -march=native -dM -E - </dev/null

#define __SSE3__ 1#define __AES__ 1などのマクロをダンプします。

5
Wei Shen

クロスコンパイラソリューションが必要な場合は、 Boost.Predef 含む

  • BOOST_Arch_は、システム/ CPUアーキテクチャ用にコンパイルしています。
  • BOOST_COMP_使用しているコンパイラの場合。
  • BOOST_LANG_コンパイル対象の言語標準の場合。
  • BOOST_LIB_C_およびBOOST_LIB_STD_は、使用中のCおよびC++標準ライブラリ用です。
  • BOOST_OS_コンパイルするオペレーティングシステム用。
  • BOOST_PLAT_オペレーティングシステムまたはコンパイラー上のプラットフォーム用。
  • BOOST_ENDIAN_ OSとアーキテクチャの組み合わせのエンディアンネス。
  • BOOST_HW_ハードウェア固有の機能。
  • BOOST_HW_SIMD SIMD(単一命令複数データ)検出用。

例えば

#if defined(BOOST_Arch_X86)
    #if BOOST_Arch_X86_64
        std::cout << "x86_64 " << BOOST_Arch_X86_64 << " \n";
    #Elif BOOST_Arch_X86_32
        std::cout << "x86 " << BOOST_Arch_X86_32 << " \n";
    #endif
#Elif defined(BOOST_Arch_ARM)
    #if _M_ARM
        std::cout << "ARM " << _M_ARM << " \n";
    #Elif _M_ARM64
        std::cout << "ARM64 " << _M_ARM64 << " \n";
    #endif
#endif

使い方の詳細については、こちらをご覧ください こちら

4
phuclv

標準はありません。ブライアンフックはこれらの束を「ポータブルオープンソースハーネス」で文書化し、一貫性のある使いやすいものにしようとしています(それに関するymmv)。このサイトのposh.hヘッダーを参照してください。

上記のリンクでは、しばらく前のDOS攻撃のために、偽のユーザーID /パスワードを入力する必要がある場合があります。

3
Michael Burr