7

初心者の質問。私はとても素敵なOcamlORAの本を読んでいます。Marshalのセクションのmagic_copyの例を試してみたところ、ターミナルよりもブラウザーに近かったので、ブラウザーのocsigenのトップレベルで試してみました、結果が得られて驚きました。

     (* js_of_ocaml *)
# let ora_magic_copy a =
  let s = Marshal.to_string a [Marshal.Closures] in
  Marshal.from_string s 0;;

val ora_magic_copy : 'a -> 'b = <fun>
# (ora_magic_copy 2 : float) +. 3.1;;

- : float = 5.1

私のマシンにインストールされているトップレベルとjs_of_ocamlで使用されているocaml2(本が書かれたときの現在のバージョン)とocaml 3.12.1の間で何かが変わったかどうかを確認し、マシンにインストールされている通常のトップレベルで同じ例を試しました。本で説明されている結果:Marshaled値のチェックに関する型システムの問題によるセグメンテーション違反。

    (* Linux toplevel *)
# (ora_magic_copy 3: float) +. 2.1;;
Segmentation fault (core dumped)

私はただ興味があります:なぜですか?

3つのケースで、Marshal.to_stringが同じ文字列を提供していることがわかります。つまり、Linuxはintをマーシャリングし、js_of_ocamlはマーシャリングし、int、js_of_ocamlはfloatをマーシャリングします。オッドマンアウトは、Linuxのトップレベルでフロートをマーシャリングすることです。

これは、javascriptの基本型を使用するjs_of_ocamlに関する何かが原因ですか?または単に...未定義の動作?

4

1 に答える 1

7

はい、あなたの問題はあなたがjavascriptトップレベルでテストしているという事実から来ています。

標準のocamlトップレベルを使用する場合、+.操作はOCamlフロート、つまりブロック内のダブルボックスで動作します。の2つのパラメーターは、その+.ようなボックスへのポインターであると予想されます。あなたの例では、ポインタの代わりに、OCaml整数2(内部的には5、つまり2 << 1 + 1として表されます)を指定します。そのため、メモリ内の位置0x5にあるはずのdoubleを読み取ろうとすると、OCamlsegfaultsが発生します。 ..

ブラウザではjs_of_ocaml、floatは単なるjavascript floatであり、integersはjavascript integersであり+.、値がタイプによってタグ付けされているため、整数とfloatを(整数をfloatに自動的に変換することによって)追加できるjavascript加算です。

于 2013-01-03T08:41:30.260 に答える