这两天在看erlang的一个probuffer库gpb的时候发现了以下代码
...
-module(gpb_scan).
...
%% User code. This is placed here to allow extra attributes.
-file("src/gpb_scan.xrl", 122).
...
里面出现了例如-file("src/gpb_scan.xrl", 122).
这样的预处理代码,第一次见到,也不记得在哪本书里面有见过,不得其解,网上也没有查到什么信息。
于是自己验证了一下,先说我的结论:
-file(文件名,行号)将改变本文件该标志以后的代码的定位文件名和行号,比如在a.erl文件里面有如下代码:
1 -module(a).
2 -export([f/0]).
3 -file("src/b.erl", 0).
4 f() ->
5 a = b.
6
看代码我们可以知道,执行a:f().将引起报错,如果没有-file,报错信息将是
no match of right hand side value b
in function a:f/0 (a.erl, line 4)
有了-file("src/b.erl", 0).
,报错信息将变成
no match of right hand side value b
in function a:f/0 (b.erl, line 1)
可见,该操作会将a.erl文件的第3行起,往后的每一行都标识为b.erl的第0+N行。
为什么我们要将错误位置定向到另一个地方去?该操作看起来很反人类,它的意义是什么?想不明白。
以下是我查找答案的过程:
生成a.erl的beam指令码, 区分加上-file("src/b.erl", 0).
与否的区别
erlc +"‘S‘" a.erl
无-file("src/b.erl", 0).
编译警告:a.erl:5: Warning: no clause will ever match
{module, a}. %% version = 0
{exports, [{f,0},{module_info,0},{module_info,1}]}.
{attributes, []}.
{labels, 7}.
{function, f, 0, 2}.
{label,1}.
{line,[{location,"a.erl",4}]}. %% 注意这行
{func_info,{atom,a},{atom,f},0}.
{label,2}.
{line,[{location,"a.erl",5}]}. %% 注意这行
{badmatch,{atom,b}}.
{function, module_info, 0, 4}.
{label,3}.
{line,[]}.
{func_info,{atom,a},{atom,module_info},0}.
{label,4}.
{move,{atom,a},{x,0}}.
{line,[]}.
{call_ext_only,1,{extfunc,erlang,get_module_info,1}}.
{function, module_info, 1, 6}.
{label,5}.
{line,[]}.
{func_info,{atom,a},{atom,module_info},1}.
{label,6}.
{move,{x,0},{x,1}}.
{move,{atom,a},{x,0}}.
{line,[]}.
{call_ext_only,2,{extfunc,erlang,get_module_info,2}}.
有-file("src/b.erl", 0).
编译警告:src/b.erl:2: Warning: no clause will ever match
{module, a}. %% version = 0
{exports, [{f,0},{module_info,0},{module_info,1}]}.
{attributes, []}.
{labels, 7}.
{function, f, 0, 2}.
{label,1}.
{line,[{location,"src/b.erl",1}]}. %% 注意这行
{func_info,{atom,a},{atom,f},0}.
{label,2}.
{line,[{location,"src/b.erl",2}]}. %% 注意这行
{badmatch,{atom,b}}.
{function, module_info, 0, 4}.
{label,3}.
{line,[]}.
{func_info,{atom,a},{atom,module_info},0}.
{label,4}.
{move,{atom,a},{x,0}}.
{line,[]}.
{call_ext_only,1,{extfunc,erlang,get_module_info,1}}.
{function, module_info, 1, 6}.
{label,5}.
{line,[]}.
{func_info,{atom,a},{atom,module_info},1}.
{label,6}.
{move,{x,0},{x,1}}.
{move,{atom,a},{x,0}}.
{line,[]}.
{call_ext_only,2,{extfunc,erlang,get_module_info,2}}.
完.
erlang 源码中的-file(文件名,行号)是个什么预处理?
原文:https://www.cnblogs.com/jlom/p/13145144.html