質問

を探していなければならないというニーズを確実に確C++のコードは32vs64ビット.私たちにしたいと思っていましたリーズナブルなソリューション-マクロが好奇心があればお知らの人々が考える場合が失敗する可能性があるというが、より良い関係ではないかと思います。だということでクロスプラットフォームに複数のコンパイラ環境です。

#if ((ULONG_MAX) == (UINT_MAX))
# define IS32BIT
#else
# define IS64BIT
#endif

#ifdef IS64BIT
DoMy64BitOperation()
#else
DoMy32BitOperation()
#endif

感謝。

役に立ちましたか?

解決

残念ながら、主要なコンパイラを横切っ64分の32ビットを定義しないクロスプラットフォームのマクロは存在しません。これを行うための最も効果的な方法は次の通りである私を見つけました。

まず、私は自分の表現を選びます。私はENVIRONMENT64 / ENVIRONMENT32を好みます。それから私は、主要なコンパイラのすべては、それが64ビット環境だかないと、私の変数を設定することを使用するかどうかを決定するために使用するものを見つけます。

// Check windows
#if _WIN32 || _WIN64
#if _WIN64
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif

// Check GCC
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif

別のより容易なルートは、単にコンパイラのコマンドラインからこれらの変数を設定することです。

他のヒント

template<int> void DoMyOperationHelper();

template<> void DoMyOperationHelper<4>() 
{
  // do 32-bits operations
}

template<> void DoMyOperationHelper<8>() 
{
  // do 64-bits operations
}

// helper function just to hide clumsy syntax
inline void DoMyOperation() { DoMyOperationHelper<sizeof(size_t)>(); }

int main()
{
  // appropriate function will be selected at compile time 
  DoMyOperation(); 

  return 0;
}

残念ながら、クロスプラットフォーム、クロスコンパイラ環境がないため信頼性高い方法でこれを純粋にコンパイルす。

  • 両_WIN32と_WIN64であ 未定義の場合、プロジェクトの設定が不良または破損(特にVisual Studio2008SP1).
  • プロジェクトラベルを付け"Win32"を設定することができまし64ビットの、プロジェクトの構成エラーになります。
  • Visual Studio2008SP1ることも多かったことも頭に付けないグレーの正しいパーツのコードによると、現在の#define.ることは困難であり、正確に把握できる#define用コンパイルす。

そのため、 法を組み合わせる 3つの簡単なチェック:

  • 1) コンパイル時間の設定, び;
  • 2) 実行時のチェック, び;
  • 3) 強固なコンパイル時にチェック.

簡易なセキュリティチェック1/3:コンパイル時間の設定

任意に選択方法 セット のに必要な#define可変となります。私はこの方法から@JaredPar:

// Check windows
#if _WIN32 || _WIN64
   #if _WIN64
     #define ENV64BIT
  #else
    #define ENV32BIT
  #endif
#endif

// Check GCC
#if __GNUC__
  #if __x86_64__ || __ppc64__
    #define ENV64BIT
  #else
    #define ENV32BIT
  #endif
#endif

簡易なセキュリティチェック2/3:実行時のチェック

メイン()をダブルチェックがsizeof()という:

#if defined(ENV64BIT)
    if (sizeof(void*) != 8)
    {
        wprintf(L"ENV64BIT: Error: pointer should be 8 bytes. Exiting.");
        exit(0);
    }
    wprintf(L"Diagnostics: we are running in 64-bit mode.\n");
#elif defined (ENV32BIT)
    if (sizeof(void*) != 4)
    {
        wprintf(L"ENV32BIT: Error: pointer should be 4 bytes. Exiting.");
        exit(0);
    }
    wprintf(L"Diagnostics: we are running in 32-bit mode.\n");
#else
    #error "Must define either ENV32BIT or ENV64BIT".
#endif

簡易なセキュリティチェック3/3:強固なコンパイル時にチェック

一般規則は"毎#defineならでの#elseを生成するエラー".

#if defined(ENV64BIT)
    // 64-bit code here.
#elif defined (ENV32BIT)
    // 32-bit code here.
#else
    // INCREASE ROBUSTNESS. ALWAYS THROW AN ERROR ON THE ELSE.
    // - What if I made a typo and checked for ENV6BIT instead of ENV64BIT?
    // - What if both ENV64BIT and ENV32BIT are not defined?
    // - What if project is corrupted, and _WIN64 and _WIN32 are not defined?
    // - What if I didn't include the required header file?
    // - What if I checked for _WIN32 first instead of second?
    //   (in Windows, both are defined in 64-bit, so this will break codebase)
    // - What if the code has just been ported to a different OS?
    // - What if there is an unknown unknown, not mentioned in this list so far?
    // I'm only human, and the mistakes above would break the *entire* codebase.
    #error "Must define either ENV32BIT or ENV64BIT"
#endif

更新2017-01-17

コメント @AI.G:

4年後だったので)できます。 実行時チェックをコンパイル時に静的主張する:static_assert(sizeof(void*)==4);.今ではすべてコンパイル時に :)

付録A

Incidentially、上記の規則に適応できる全てのコードベースの信頼性:

  • 毎場合(計算書に終わる。"else"を生成する警告やエラーとなります。
  • 各スイッチ()計算書に終わる"デフォルト"を生成する警告やエラーとなります。

そこで力をお考えのシングルの場合は、事前になるものである欠陥のある)ロジックは、"else"の部分を実行し、正しいコードです。

この技術は多くのその他)を書く30,000線プロジェクトを作成し、奥日から最初に展開され製品化した12ヶ月間となりました。

これは、開始のためのWindows上で動作しません。ロングスとint型を使用すると、32ビットまたは64ビット版のWindows用にコンパイルしているかどうか、両方の32ビットです。私は、ポインタのサイズは8バイトであるかどうかをチェックすることは、おそらく、より信頼性の高いルートであると思うだろう。

あなたはこれを行うことができます:

#if __WORDSIZE == 64
char *size = "64bits";
#else
char *size = "32bits";
#endif
Try this:
#ifdef _WIN64
// 64 bit code
#elif _WIN32
// 32 bit code
#else
   if(sizeof(void*)==4)

       // 32 bit code
   else 

       // 64 bit code   
#endif

"64ビットでコンパイル" はウェルC ++で定義されていません。

C ++のようなint型、長いvoid *ようなサイズのための唯一の下限を設定します。 intは64ビットプラットフォーム用にコンパイルされた64ビットの場合もあるという保証はありません。モデルは、例えば、を可能にします23ビットints及びsizeof(int *) != sizeof(char *)

noreferrer">プログラミングモデルは、64ビット・プラットフォーム用のをrel="nofollow href="http://www.unix.org/version2/whatsnew/lp64_wp.html"異なる

あなたの最善の策は、プラットフォーム固有のテストです。あなたの最良の第二、ポータブル決定は、より具体的でなければならない。のものをは64ビットます。

あなたのアプローチはあまりにも遠くはありませんでしたが、あなただけのlongintは、同じサイズのものであるかどうかをチェックされています。理論的には、彼らは両方の32ビットとの両方を想定して、あなたのチェックが失敗した場合には64ビットである可能性があります。ここでは、実際の型そのものの大きさではなく、それらの相対的なサイズをチェックし、チェックがあります:

#if ((UINT_MAX) == 0xffffffffu)
    #define INT_IS32BIT
#else
    #define INT_IS64BIT
#endif
#if ((ULONG_MAX) == 0xfffffffful)
    #define LONG_IS32BIT
#else
    #define LONG_IS64BIT
#endif

原則として、あなたは最大値でマクロ定義されたシステムを持っている任意のタイプのためにこれを行うことができます。

標準も32ビットシステムでは、少なくとも64ビットであることlong longを必要とすることを

注、

人々は、すでにプログラムが32-bitまたは64-bitにコンパイルされているかどうかを判断しようとする方法を提案します。

そして、私はあなたがアーキテクチャでは、あなたはそれが(「リラックスする」)と思われるものであることを確認するために、C ++ 11の機能static_assertを使用することができることを追加したい。

あなたがマクロを定義する代わりにそうます:

#if ...
# define IS32BIT
  static_assert(sizeof(void *) == 4, "Error: The Arch is not what I think it is")
#elif ...
# define IS64BIT
  static_assert(sizeof(void *) == 8, "Error: The Arch is not what I think it is")
#else
# error "Cannot determine the Arch"
#endif

コードの下には、最新の環境のために正常に動作します:

  #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) &&     !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
    #define IS64BIT 1
 #else
    #define IS32BIT 1
#endif

すべてのあなたの環境でのプロジェクト構成を使用することができる場合、それは簡単に64ビットおよび32ビットのシンボルを定義するだろう。ですから、このようなプロジェクト構成を持っていると思います:

32ビットデバッグ
32ビットリリース
64ビットのデバッグ
64ビットリリース

EDIT:これらは、一般的な構成である構成を標的化さではありません。あなたが欲しいものは何でもそれらを呼び出すます。

あなたがそれを行うことができない場合は、

、私はジャレッドのアイデアを気に入っています。

私は別のファイルで32ビットと64ビットのソースを配置し、ビルドシステムを使用して、適切なソースファイルを選択すると思います。

私はこの答えとして利用の場合、完全な例では、実行時のチェックに記載の 他の答え.

このアプローチしていを伝えるエンドユーザーかどうかのプログラム集として64ビットと32ビット(またはその他る):

バージョン。h

#ifndef MY_VERSION
#define MY_VERSION

#include <string>

const std::string version = "0.09";
const std::string arch = (std::to_string(sizeof(void*) * 8) + "-bit");

#endif

test.cc

#include <iostream>
#include "version.h"

int main()
{
    std::cerr << "My App v" << version << " [" << arch << "]" << std::endl;
}

コンパイルおよび試験

g++ -g test.cc
./a.out
My App v0.09 [64-bit]
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top