function - 在语言层面, `ccall` 到底是什么?

标签 function syntax macros julia ffi

我是 Julia 的新手,我试图在语言层面上理解 ccall 是。在语法级别,它看起来像一个普通函数,但它在获取参数方面的行为显然不同:

Note that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression.



此外,如果我评估绑定(bind)到 Julia REPL 中的函数的变量,我会得到类似
julia> max
max (generic function with 15 methods)

但如果我尝试对 ccall 做同样的事情:
julia> ccall
ERROR: syntax: invalid "ccall" syntax

显然,ccall是一种特殊的语法,但它也不是宏(没有 @ 前缀,并且无效的宏使用会给出更具体的错误)。那么,它是什么?它是语言中的某种东西,还是我可以用一些我不熟悉的语言结构来定义自己的东西?

如果它是一些内置的语法,为什么决定使用函数调用表示法,而不是将其实现为宏或设计更具可读性和独特的语法?

最佳答案

在当前的每晚(以及即将发布的 0.6 版本)中,您观察到的许多特殊行为 has been removed (见 this pull-request)。 ccall不再是保留字,因此可以用作函数或宏名称。

但是仍然有一点奇怪:定义一个名为 ccall 的 3 或 4 参数函数。是允许的,但实际上调用这样的函数会给出一个关于 ccall argument types 的错误。 (其他数量的参数都可以)。原因直接指向您的问题:

So, what is it? Is it something baked into the language



是的,ccall ,尽管它在 0.6 中不再是关键字,但仍以多种方式“融入”该语言:
  • :ccall([four args...])表达形式被识别和specially handled在语法降低期间。这个降低步骤做了几件事,包括在对 unsafe_convert 的调用中包装参数。 ,它允许从 Julia 对象到 C 兼容对象的自定义转换;以及提取可能需要 rooted 的参数防止在 ccall 期间对引用对象进行垃圾收集. (见 code_lowered 输出,或尝试 expand 函数;有关编译器的更多信息 here )。
  • ccall需要 extensive handling在代码生成后端,包括:在指定的共享库中查找请求的函数名,生成LLVM call 指令——最终由 LLVM 即时编译器转换为特定于平台的机器代码。 (参见 code_llvmcode_native 的不同阶段)。

  • And if it is some baked-in piece of syntax, why was it decided to use function call notation, instead of implementing it as a macro or designing a more readable and distinct syntax?



    由于上述原因,ccall无论它看起来像宏还是函数,都需要特殊处理。在 this mailing list thread ,其中一位 Julia 创作者 (Stefan Karpinski) 评论了为什么不将其设为宏:

    I suppose we could reimplement it as a macro, but that would really just be pushing the magic further down.



    至于“更具可读性和独特的语法”,也许这是一个品味问题。我不清楚为什么其他语法更可取(除了 LuaJIT/CFFI 风格的内联 C 语法解析的便利性,我是其中的粉丝)。我唯一强烈的个人愿望 ccall将输入相邻的参数和类型(例如 ccall((:foo, :libbar), Void, (x::Int, y::Float)) ),因为使用较长的参数列表可能不方便。在 0.6 中,可以将这种形式实现为宏!

    关于function - 在语言层面, `ccall` 到底是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42262122/

    相关文章:

    c++ - 类的映射函数

    wordpress - apply_filters(...) 在 WordPress 中实际上做了什么?

    function - ReactJS:使用 material-ui 获取多个复选框值

    PHPExcel 验证一系列单元格的数据

    haskell - 如何写 return Haskell

    c++ - 这个c++宏在做什么?

    macros - 如何建立在宏展开期间处于事件状态的变量绑定(bind)?

    c - 将修改后的数组值传递回 C 中的主函数

    javascript - javascript 和返回值的问题

    syntax - Crystal 语法程序(Crystal Reports)