简体   繁体   English

为什么erlang:foo()编译?

[英]Why does erlang:foo() compile?

Why doesn't the Erlang compiler detect undefined functions in compile time. 为什么Erlang编译器在编译时没有检测到未定义的函数。

If I write test.erl: 如果我写test.erl:

-module(test). 
-export([start/0]).

start() ->
       erlang:foo().

It compiles fine. 它汇编得很好。

Eshell V5.6.5  (abort with ^G)
1> c(test).
{ok,test}
2> 

But crashes runtime. 但崩溃运行时。

2> test:start().
** exception error: undefined function erlang:foo/0

Why doesn't the compiler issue an error or a warning about this during compilation? 为什么编译器在编译期间没有发出错误或警告? It should know about exported functions, shouldn't it? 它应该知道导出的功能,不应该吗?

Erlang is a dynamic language. Erlang是一种动态语言。 It is good practice however to do type checking and static analysis post-compilation . 然而,在编译后进行类型检查和静态分析是一种很好的做法。

The tool Dialyzer is used to check for this sort of error condition. Dialyzer工具用于检查此类错误情况。

The reason the compiler doesn't know about it at compile time is because functions can be searched for and dynamically loaded from the code path at run time (and also from a remote node). 编译器在编译时不知道它的原因是因为可以在运行时(以及从远程节点)从代码路径中搜索和动态加载函数。 The Dialyzer will check the code against the code path at the time it is run. 透析器将在运行时根据代码路径检查代码。

The ability to load code from a remote node means that basic 'systems' can be installed on a device and the device can then bootstrap itself from the network. 从远程节点加载代码的能力意味着可以在设备上安装基本的“系统”,然后设备可以从网络引导自身。

You should also remember another characteristic of Erlang that you can generate function calls on the fly using constructs like: 你应该还记得二郎,你可以生成函数调用的另一个特点在飞行中使用结构,如:

erlang:apply(ModuleName, FunctionName, ArgList)

so in that case it is simply not possible to know if the function exists at compile time or not. 所以在这种情况下,根本不可能知道函数是否在编译时存在。

And although the module and function might exist now at compile time, you can hot swap modules out and unload code, so it may not be there at run time. 虽然模块和函数现在可能在编译时存在,但您可以热插拔模块并卸载代码,因此在运行时可能不存在。

You may use the xref application to check the usage of deprecated, undefined and unused functions (and more!). 您可以使用xref应用程序来检查已弃用,未定义和未使用的函数的使用情况(以及更多!)。

Compile the module with debug_info : 使用debug_info编译模块:

Eshell V6.2  (abort with ^G)
1> c(test, debug_info).
{ok,test}

Check the module with xref:m/1 : 使用xref:m/1检查模块:

2> xref:m(test).
[{deprecated,[]},
 {undefined,[{{test,start,0},{erlang,foo,0}}]},
 {unused,[]}]

You may want to check out more about xref here: 您可以在此处查看有关xref更多信息:

Erlang -- Xref - The Cross Reference Tool (Tools User's Guide) Erlang - 外部参照 - 交叉参考工具(工具用户指南)

Erlang -- xref (Tools Reference Manual) Erlang - xref(工具参考手册)

I think that this is an implementation question as the Erlang developers decided to to runtime linking rather than build-time linking. 我认为这是一个实现问题,因为Erlang开发人员决定运行时链接而不是构建时链接。 Part of the reason may have something to do versioning and/or dynamic code loading. 部分原因可能是版本控制和/或动态代码加载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM