是否可以在运行时检查OCaml中行为不佳的本机函数?这在C/OCaml混合项目中很有用。
在C中实现固有的OCaml函数时,必须注意与运行时和谐相处。
例如,在下面的示例中,libadd
中的add
故意不适当地使用CAMLreturn
。
(* foo.ml *)
external add : int -> int -> int = "add";;
Printf.printf "%d\n" (add 4 5);;
和C源文件
// libadd.c
#include <caml/memory.h>
#include <caml/mlvalues.h>
CAMLprim value
add(value ml_x, value ml_y)
{
CAMLparam2(ml_x, ml_y);
long x = Long_val(ml_x);
long y = Long_val(ml_y);
// intentional mistake here
// don't use CAMLreturn
return Val_long(x + y);
}
如果使用任一OCaml编译器编译此代码
$ ocamlopt foo.ml libadd.c
$ ocamlc -custom foo.ml libadd.c
然后a.out
就会毫无问题地打印出9
。
./a.out
9
有没有办法让任何一个编译器围绕本机函数调用发出额外的检查,以检查是否遵守了OCaml调用约定?
发布于 2018-06-04 00:57:26
ocaml没有对这个问题做任何处理,错误依赖于由gcc编译的C代码。而gcc无法检查返回是否与Ocaml兼容。
对于Ocaml来说,限制错误编写C语言的一种方法是重新定义return
以避免使用它:
#define return _forbidden_
如果在代码中包含了那些定义的代码,那么初始的C代码将无法编译。
它不能解决这个问题,但强制用户注意函数返回的方式可能是有用的。
另一种方法是让一个健全的脚本检查任何返回类型为CAML*
的函数是否不包含任何return
...
发布于 2018-06-05 16:58:25
CAML宏只是简单的预处理器宏。您总是可以直接编写底层C代码,而不是使用宏。除了让gcc知道如何与ocaml交互之外,没有什么能解决这个问题的。
匹配BEGIN和END样式的宏有一个简单的技巧,但是如果意外忘记了其中之一,就会失败。诀窍是在BEGIN宏中有一个开始{,在END宏中有一个结束}。忘记其中的一个会给出一个错误,因为{}不平衡。
问题是一个函数可以有多个返回语句,这使得不平衡的{}的使用变得不可能。
https://stackoverflow.com/questions/50663197
复制相似问题