18

C99boolデータ型を使用するライブラリがあり、FFI 経由で呼び出したいと考えています。

HaskellのC99 boolに対応する型は何ですか? Foreign.C.typesには、CInt、CShort などがありますが、CBool​​ はありません

の「正しい」型がない場合bool、 を期待する関数に渡される安全な代替型は何boolですか?

別の方法として C ライブラリを変更することもできますが、そのまま維持したいと考えています。

4

5 に答える 5

12

は 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 をまったくサポートしていません。

于 2013-03-12T19:00:20.950 に答える
2

私の知る限り、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 関数のラッパーを作成して、型キャストで関数に渡すほうがよいと思います。

于 2013-03-12T18:59:12.070 に答える
1

boolas パラメーターを持つこととbool結果の型を持つことには違いがあります。


C99 より前の BOOL は関数の戻り値の型として十分ではなかったため、C99 bool が導入された (そして他のすべての基本値とは異なる) ことは確かです。

そのような変数のメモリ内表現が少なくとも 1 バイト存在する必要がありますが...

  1. アセンブラ レベルでのブール値の処理は、FLAG 依存の goto を介して行われます。(&& および || を参照)

  2. より高速なビットごとの & および | を使用できるはずです。&& と || の代わりに ブール値を 1 ビットにする必要があるブール値。

  3. 関数の戻り値は、INT レジスタの 1 ビットを強制的に使用したり、INT レジスタでゼロ/非ゼロの int を使用したりする代わりに、(一部のマシンでは) FLAG レジスタを使用できる必要があります。

3. のせいで、各プラットフォームでの C99 bool の使用の ABI (Application Binary Interface) を考慮しない限り、これに対する直接的な解決策はありません。Haskell コンパイラにパッチを適用して、C99-bool の結果型を持つ/持つべきである、インポート/エクスポートされた各 C 関数をラップする方が簡単な場合があります。


私の記憶が正しければ、C 関数のパラメーターリストにあるintほとんどの基本的な C 型の安全な代替手段です。しかし、CChar はおそらく bool に対しても同じ (またはそれ以上) を行うでしょう。で使用される可変引数パラメータ機能について読みたいと思うかもしれません。,...)printf

于 2013-03-21T15:38:10.063 に答える