C99bool
データ型を使用するライブラリがあり、FFI 経由で呼び出したいと考えています。
HaskellのC99 boolに対応する型は何ですか? Foreign.C.typesには、CInt、CShort などがありますが、CBool はありません。
の「正しい」型がない場合bool
、 を期待する関数に渡される安全な代替型は何bool
ですか?
別の方法として C ライブラリを変更することもできますが、そのまま維持したいと考えています。
は C99 で実装定義されているためsizeof(_Bool)
(ISO/IEC 9899:1999 6.2.5、6.2.6、および 6.5.3.4/4 を参照)、明らかな移植性のある解決策は、int
代わりに を使用するラッパーを介してそのような関数を呼び出すことですbool
。または、移植性を気にしない場合は、コンパイラのドキュメントをチェックしてsizeof(_Bool)
、プラットフォームに何があるかを調べ、対応する FFI タイプを使用することができます。
CBool
欠席の理由についての私の推測はForeign.C.Types
、基礎となる C 実装が C99 のすべての機能をサポートすることが期待されていないということです。非常に広く使用されているコンパイラ (MSVC) の 1 つは、C99 をまったくサポートしていません。
私の知る限り、C99 は_Bool
型の正確なサイズを定義していません (そしてbool
にマップされてい_Bool
ます)。あなたがそれについて知っている唯一のことは、それが値を保持するのに十分な大きさであること0
です1
. したがって、そのバイナリ表現はコンパイラに依存します。そのため、FFI サポート ライブラリには存在しないと思います。
GCC 4.7.2 でコンパイルされた次のプログラム:
#include <stdio.h>
#include <stdbool.h>
int main() {
printf("%d", sizeof(bool));
return 0;
}
次の出力が得られます。
% gcc -std=c99 -o test test.c
% ./test
1
そのため、GCCbool
にマップされているようです。char
表示される内容は、コンパイラによって異なります。
int
このため、完全な移植性が必要な場合は、C 関数のラッパーを作成して、型キャストで関数に渡すほうがよいと思います。
bool
as パラメーターを持つこととbool
結果の型を持つことには違いがあります。
C99 より前の BOOL は関数の戻り値の型として十分ではなかったため、C99 bool が導入された (そして他のすべての基本値とは異なる) ことは確かです。
そのような変数のメモリ内表現が少なくとも 1 バイト存在する必要がありますが...
アセンブラ レベルでのブール値の処理は、FLAG 依存の goto を介して行われます。(&& および || を参照)
より高速なビットごとの & および | を使用できるはずです。&& と || の代わりに ブール値を 1 ビットにする必要があるブール値。
関数の戻り値は、INT レジスタの 1 ビットを強制的に使用したり、INT レジスタでゼロ/非ゼロの int を使用したりする代わりに、(一部のマシンでは) FLAG レジスタを使用できる必要があります。
3. のせいで、各プラットフォームでの C99 bool の使用の ABI (Application Binary Interface) を考慮しない限り、これに対する直接的な解決策はありません。Haskell コンパイラにパッチを適用して、C99-bool の結果型を持つ/持つべきである、インポート/エクスポートされた各 C 関数をラップする方が簡単な場合があります。
私の記憶が正しければ、C 関数のパラメーターリストにあるint
ほとんどの基本的な C 型の安全な代替手段です。しかし、CChar はおそらく bool に対しても同じ (またはそれ以上) を行うでしょう。で使用される可変引数パラメータ機能について読みたいと思うかもしれません。,...)
printf