2016-04-04 4 views
1

私は以下のコードをapi(cdecl)の一部として持っています。 MSVC++では、sizeof boolは1バイトですが、boolは実装が定義されているため、他のコンパイラでコンパイルされたプログラム/関数の作成者が誤って関数のシグネチャを定義すると、boolが> 1バイトとして扱われる可能性があります。boolの戻り値を持つ関数は、レジスタ全体の1バイトのみを設定します。

virtual bool isValid() 
{ 
    return false; 
    //^code above in asm: xor al, al 
} 

はこれを避けるために、私が戻る前に、インラインアセンブラ、xor eax, eaxを置く - 私はそれは少しハック感じ、それはもちろんにより、インラインアセンブラのサポートの欠如にx64の上では動作しません。

#define bool intを使用すると、うまくいかない場合があります。その中にboolデータ型を持つ構造体があり、これを使用すると破損が発生します。

eax/raxレジスタをゼロにすることができる組み込み関数など、この問題を解決できるものはありますか?

+5

異なるコンパイラによって生成された2つのライブラリは、実装定義の機能を使用して通信しようとします。あなたはこの写真に間違ったことを見ますか? – dasblinkenlight

+0

これは驚くかもしれませんが、ほとんどの基本的な型のサイズは実装定義です。 'int'はこれに関して' bool'と変わりありません。 – SergeyA

+0

msvC++のみであるはずですが、プラグインのサポートを追加するとどうなるか分かります。特定のプログラムはx86上で4バイトのシグネチャを使用しているので、この場合は 'int'が動作するはずです。 –

答えて

5

あなたが求めていることは何もありません。あなたの問題には、はるかに異なる解決策が必要です。

最初に、「関数の署名を誤って定義する」コードが壊れているため、修正が必要です。他のコードで回避することは決して解決策ではありません。

次の問題は、実装が定義されているばかりのbool以上のようなものです.C++標準では、実装の定義がホスト全体になります。 2つの異なるC++コンパイラで互換性のあるABIがあることはめったにありません。あなたのコードが他の人がコンパイルしたコードを使用するためのC++インターフェイスを提供している場合は、サポートしたいコンパイラごとに、オブジェクトファイル、スタティックライブラリ、DLLまたは実行可能ファイルの形式で別々にコンパイルされたバイナリを作成する必要があります。実際には、各コンパイラのバージョンごとに別々のバイナリを用意する必要があるかもしれません。

Microsoft C++ ABIと互換性のある2つのC++コンパイラがあります。最初はIntel's C++ compiler、次はthe Windows port of clangです。 clangの実装は、依然として進行中の作業です。コードがコンパイルされたMicrosoft C/C++ランタイムライブラリのバージョンごとに別々のバージョンを作成する必要があります。

コードに純粋なCインターフェイスを提供することで、配布する必要があるバイナリのバージョンを減らすことができます。純粋なCインタフェースは、Cデータ型のみを使用し、extern "C"と宣言された関数のみを使用することを意味します。クラス、メンバー関数、テンプレート、RTTI、例外などのものは実装で使用できますが、パブリックインターフェイスの一部としては使用できません。例外は、COMのようなインタフェースであり、パブリックな純粋な仮想関数だけを持つクラスです。 Windows用のCコンパイラはすべて基本的に同じC ABIを使用し、COMインターフェイスをサポートしているため、互換性の問題はそれほど問題になりません。しかし、boolタイプ(実際にはCの_Boolタイプ)は、C言語への比較的最近の追加なので、おそらく安全ではありません。代わりにCインターフェイスでintを使用してください。

MicrosoftのVisual C++コンパイラで使用するコンパイル済みバイナリをすべて配布する場合でも、コンパイラの各バージョンごとにバージョンを配布する必要がある場合がありますが、C/C++ランタイムの違いにより、これは、各バージョンに異なるランタイム実装が付属し、互換性のない内部レイアウトを持つデータ構造を持つためです。あるバージョンのVisual C++でコンパイルされた関数で作成されたSTLコンテナを別のバージョンでコンパイルされた関数に渡すことはできません。実行ファイルとDLLが異なるバージョンのCランタイムを使用する場合、mallocを実行可能ファイルに、freeをDLLに割り当てることはできません。

残念ながら、ユーザーを1つの特定のコンパイラに制限したくない場合は、探している問題の簡単な解決策が存在しない可能性があります。これは、プラグインのサポートを提供するプログラムで使用される一般的な解決策であることに注意してください。 Puginsは、実行可能ファイルをコンパイルした同じコンパイラの同じバージョンをコンパイルする必要があります。

関連する問題