[英]Why does erlang:foo() compile?
为什么Erlang编译器在编译时没有检测到未定义的函数。
如果我写test.erl:
-module(test).
-export([start/0]).
start() ->
erlang:foo().
它汇编得很好。
Eshell V5.6.5 (abort with ^G)
1> c(test).
{ok,test}
2>
但崩溃运行时。
2> test:start().
** exception error: undefined function erlang:foo/0
为什么编译器在编译期间没有发出错误或警告? 它应该知道导出的功能,不应该吗?
Erlang是一种动态语言。 然而,在编译后进行类型检查和静态分析是一种很好的做法。
Dialyzer工具用于检查此类错误情况。
编译器在编译时不知道它的原因是因为可以在运行时(以及从远程节点)从代码路径中搜索和动态加载函数。 透析器将在运行时根据代码路径检查代码。
从远程节点加载代码的能力意味着可以在设备上安装基本的“系统”,然后设备可以从网络引导自身。
你应该还记得二郎,你可以生成函数调用的另一个特点在飞行中使用结构,如:
erlang:apply(ModuleName, FunctionName, ArgList)
所以在这种情况下,根本不可能知道函数是否在编译时存在。
虽然模块和函数现在可能在编译时存在,但您可以热插拔模块并卸载代码,因此在运行时可能不存在。
您可以使用xref
应用程序来检查已弃用,未定义和未使用的函数的使用情况(以及更多!)。
使用debug_info
编译模块:
Eshell V6.2 (abort with ^G)
1> c(test, debug_info).
{ok,test}
使用xref:m/1
检查模块:
2> xref:m(test).
[{deprecated,[]},
{undefined,[{{test,start,0},{erlang,foo,0}}]},
{unused,[]}]
您可以在此处查看有关xref
更多信息:
我认为这是一个实现问题,因为Erlang开发人员决定运行时链接而不是构建时链接。 部分原因可能是版本控制和/或动态代码加载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.