7

新手问题。我正在阅读非常好的Ocaml ORA书。当我去玩 Marshal 部分中的 magic_copy 示例时,我更接近于浏览器而不是终端,所以我在 ocsigen 的toplevel in a browser中尝试了它,我很惊讶地得到了结果:

     (* 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

检查 ocaml 2(本书编写时的当前版本)和 ocaml 3.12.1 之间是否发生了变化,由我的机器上安装的顶层和 js_of_ocaml 使用,我在我的机器上安装的普通顶层中尝试了相同的示例并得到了书中解释的结果:由于类型系统检查 Marshaled 值的麻烦而导致的段错误。

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

我只是好奇:为什么?

我看到在三种情况下,Marshal.to_string 给出了相同的字符串:linux marshalling an int,js_of_ocaml marshalling and int,js_of_ocaml marshalling a float。奇怪的人是 linux 顶级编组一个浮点数。

这是因为 js_of_ocaml 使用了 javascript 的基本类型吗?或者只是......未定义的行为?

4

1 回答 1

7

是的,您的问题来自您在 javascript 顶层进行测试的事实。

当您使用标准ocaml顶层时,该+.操作对 OCaml 浮点数进行操作,即块内的双盒,+.预期的两个参数是指向此类盒的指针。在您的示例中,您给出的是 OCaml 整数而不是指针2(在内部,它表示为 5,即 2 << 1 + 1),因此 OCaml 在尝试读取应该位于内存中位置 0x5 的双精度时会出现段错误。 ..

js_of_ocaml浏览器中,浮点数只是javascript浮点数,整数是javascript整数,+.是javascript的加法,可以将整数和浮点数相加(通过自动将整数转换为浮点数),因为值是由它们的类型标记的。

于 2013-01-03T08:41:30.260 回答