查看源代码 编译器发布说明
本文档描述了对编译器应用程序所做的更改。
编译器 8.5.4
修复的错误和故障
修复了公共子表达式消除过程中的崩溃问题。
修复了一个错误,该错误会导致连续调用
erlang:setelement/2
时生成错误代码,可能导致运行时系统崩溃。当使用
line_coverage
选项时,异常可能会显示错误的异常抛出位置行号。自有 ID:OTP-19282 辅助 ID:PR-8907
如果在模块内的
compile()
属性中给出了line_coverage
选项,则该选项会被忽略。二进制生成器中与浮点数匹配的段现在会跳过任何无效的浮点数(例如 NaN),并继续匹配二进制的其余部分。在此修复之前,一旦遇到无效的浮点数,推导式就会停止。
示例
1> BadFloat = <<-1:64>>. <<"ÿÿÿÿÿÿÿÿ">> 2> [X || <<X:64/float>> <= <<0.0/float,BadFloat/binary,42.0/float>>]. [0.0,42.0]
自有 ID:OTP-19331 辅助 ID:PR-8978
编译器 8.5.3
修复的错误和故障
在极少数情况下,当不安全时,可能会应用破坏性的元组更新优化。
在极少数情况下,涉及追加多个二进制文件时,编译器可能会发出不安全的代码,从而导致运行时系统崩溃。
编译器 8.5.2
修复的错误和故障
修复了与追加二进制文件相关的优化过程中的崩溃问题。
自有 ID:OTP-19168 辅助 ID:GH-8630
修复了编译器别名分析过程中的一个错误,该错误可能导致其发出不安全的代码。
自有 ID:OTP-19178 辅助 ID:PR-8686
编译器 8.5.1
修复的错误和故障
编译器的优化过程之一在编译某些模块时会变得非常慢。现在,对于会触发速度减慢的输入,编译器将自动禁用该过程。
自有 ID:OTP-19131 辅助 ID:PR-8567
修复了
+deterministic
以使其与文档属性正常工作。
编译器 8.5
修复的错误和故障
二进制推导式的生成器可以在得知它们将被需要之前进行计算。如果稍后不应进行计算的生成器失败,则可能导致二进制推导式失败。
例如,考虑以下模块
-module(t). -export([f/0]). f() -> <<0 || _ <- [], _ <- ok, false>>.
在 Erlang/OTP 26 中,它会像这样失败
1> t:f(). ** exception error: bad generator ok in function t:f/0 (t.erl, line 6)
在 Erlang/OTP 27 中,它返回一个空二进制文件
1> t:f(). <<>>
预处理器文档现在提到可以在
-if
或-elif
指令的条件中调用defined(Name)
来测试Name
是否为定义的宏的名称。(此功能在 OTP 21 中实现。)如果
-if
或-elif
中具有不是保护 BIF 名称的名称的函数调用,则不会出现编译错误,而是会导致跳过该指令后面的行。现在已更改为编译错误。潜在的不兼容性
改进和新功能
现在,编译器会为函数头不匹配发出更友好的错误消息。例如,给定
a() -> ok; a(_) -> error.
Erlang/OTP 26 及更早版本会发出类似的诊断信息
t.erl:6:1: head mismatch % 6| a(_) -> error. % | ^
而在 Erlang/OTP 27 中,诊断信息类似于
t.erl:6:1: head mismatch: function a with arities 0 and 1 is regarded as two distinct functions. Is the number of arguments incorrect or is the semicolon in a/0 unwanted? % 6| a(_) -> error. % | ^
自有 ID:OTP-18648 辅助 ID:PR-7383
现在,编译器优化了已知为常量的二进制文件的创建。
考虑以下示例
bin() -> C = char(), <<C>>. char() -> $*.
本质上,编译器将示例重写为稍微更高效的
bin() -> _ = char(), <<$*>>. char() -> $*.
自有 ID:OTP-18673 辅助 ID:PR-7474, ERIERL-964
现在,编译器将合并同一记录的连续更新。
例如,以下函数的正文将合并为单个元组创建指令
-record(r, {a,b,c,d}). update(Value) -> R0 = #r{}, R1 = R0#r{a=Value}, R2 = R1#r{b=2}, R2#r{c=3}.
提高了别名分析过程的性能。
现在,
-spec
属性用于文档。自有 ID:OTP-18801 辅助 ID:PR-7739
JIT 中已实现本机覆盖率支持。当运行覆盖编译的代码时,它将自动被
cover
工具使用,以减少执行开销。还有新的 API 支持不使用
cover
工具的本机覆盖率。要为本机覆盖率检测代码,必须使用
line_coverage
选项进行编译。要在运行时系统中启用本机覆盖率,请像这样启动它
$ erl +JPcover true
还有以下用于支持本机覆盖率的新函数
code:coverage_support/0
code:get_coverage/2
code:reset_coverage/1
code:get_coverage_mode/0
code:get_coverage_mode/1
code:set_coverage_mode/1
自有 ID:OTP-18856 辅助 ID:PR-7856
EEP-59 - 文档属性 已实现。
文档属性可用于记录函数、类型、回调和模块。关键字
-moduledoc "此处为文档"。
用于记录模块,而-doc "此处为文档"。
可用于函数、类型和回调的顶部,以分别记录它们。类型、回调和函数文档可以通过
-doc false
或-doc hidden
设置为hidden
。当文档属性将类型标记为隐藏时,它们将不会成为文档的一部分。默认情况下,
moduledoc
和doc
中的文档会按照 EEP-48 的格式添加到二进制 beam 文件中。当导出的函数、类型和回调中缺少
-doc
属性时,使用编译器标志warn_missing_doc
会引发警告。当文档化的函数、类型和回调中缺少 spec 属性时,使用编译器标志
warn_missing_spec_documented
会引发警告。moduledoc
和doc
可以引用要嵌入的外部文件,例如-doc {file, "README.md"}.
,它引用当前工作目录中找到的文件README.md
。编译器会警告其 spec 引用隐藏类型的导出函数。因此,当在导出函数中使用隐藏类型(即该类型不是文档的一部分)时,会发出警告。
自有 ID:OTP-18916 辅助 ID:PR-7936
文档已迁移为使用 Markdown 和 ExDoc。
自有 ID:OTP-18955 辅助 ID:PR-8026
编译器查找选项的顺序已更改。
当
-compile()
属性中给出的编译器选项与传递给编译器的选项发生冲突时,-compile()
属性中给出的选项会覆盖传递给编译器的选项,而后者又会覆盖ERL_COMPILER_OPTIONS
环境变量中给出的选项。示例
如果
some_module.erl
具有以下属性-compile([nowarn_missing_spec]).
并且编译器像这样调用
% erlc +warn_missing_spec some_module.erl
则不会为任何没有 spec 的函数发出警告。
潜在的不兼容性
在编译器和运行时系统中实现了元组的安全破坏性更新。这允许 VM 在安全的情况下就地更新元组,从而通过减少复制以及减少垃圾产生来提高性能。
示例
-record(rec, {a,b,c}). update(#rec{a=needs_update,b=N}=R0) -> R = R0#rec{a=up_to_date}, if N < 0 -> R#rec{c=negative}; N == 0 -> R#rec{c=zero}; N > 0 -> R#rec{c=positive} end.
if
的三个子句中的每一个中的记录更新都可以安全地就地完成,因为变量R
不会再次使用。自有 ID:OTP-18972 辅助 ID:PR-8090
稍微改进了匹配上下文重用优化,允许将匹配上下文按原样传递给
bit_size/1
和byte_size/1
。自有 ID:OTP-18987
erl_lint
(以及扩展的compiler
)现在会警告使用已弃用回调的代码。目前唯一被弃用的回调函数是
format_status/2
,它存在于gen_server
、gen_event
和gen_statem
中。你可以使用
nowarn_deprecated_callback
来静默警告。内部 ID: OTP-19010 辅助 ID: PR-8205
编译器 8.4.3.2
修复的 Bug 和故障
修复了连续调用 erlang:setelement/2 时会生成错误代码,并可能导致模拟器崩溃的 bug。
内部 ID: OTP-19270 辅助 ID: GH-8783 PR-8898
编译器 8.4.3.1
修复的 Bug 和故障
修复了与追加二进制文件相关的优化过程中的崩溃问题。
内部 ID: OTP-19168 辅助 ID: GH-8630
修复了编译器别名分析过程中的一个错误,该错误可能导致其发出不安全的代码。
内部 ID: OTP-19178 辅助 ID: PR-8686
编译器 8.4.3
修复的 Bug 和故障
在极少数情况下,编译器代码会为位语法匹配生成不安全的代码。
内部 ID: OTP-19019
在极少数情况下,本应成功的二进制匹配失败。
内部 ID: OTP-19035 辅助 ID: GH-8280, PR-8284
修复了一个 bug,当满足以下所有条件时,函数的环境可能会被参数覆盖
- 该函数在调用它的模块中声明。
- 该函数的目标是静态已知的。
- 调用该函数时,额外的参数数量等于环境变量的数量。
内部 ID: OTP-19045 辅助 ID: GH-8316
编译器 8.4.2
修复的 Bug 和故障
在极少数情况下,不安全的优化可能导致编译器为列表匹配生成不正确的代码。
内部 ID: OTP-19003 辅助 ID: GH-8187, PR-8189
改进和新特性
修复了编译服务器,使其在
erlc
调用之间其 lib 目录中的应用程序发生更改时重新启动。内部 ID: OTP-18936
编译器 8.4.1
修复的 Bug 和故障
对于包含巨大函数的模块,编译器可能会变得非常慢。
内部 ID: OTP-18770 辅助 ID: GH-7667, PR-7672
编译器 8.4
修复的 Bug 和故障
当编译使用巨大的正元组大小调用
is_record/3
时,编译器可能会永远运行下去。在函数体中使用调用is_record(A, a, 0)
会使编译器崩溃。当在保护语句中使用时,编译器会发出不正确的代码,该代码会接受{a>
作为记录。内部 ID: OTP-18605 辅助 ID: GH-7298, GH-7317
修复了当分析包含字面量原子
undefined
在段大小中的错误代码时导致 dialyzer 崩溃的 bug。内部 ID: OTP-18629 辅助 ID: GH-7325
当编译一些包含对
erlang:load_nif/2
的调用的模块时,编译器会崩溃。内部 ID: OTP-18662 辅助 ID: GH-7409, PR-7416
修复了一个导致编译器在合法代码上崩溃的 bug。
内部 ID: OTP-18678 辅助 ID: GH-7488
当尝试编译复杂表达式中对
is_list/1
的调用时,编译器可能会崩溃。内部 ID: OTP-18689 辅助 ID: GH-7504, PR-7518
当一个复杂的保护表达式使用
or
运算符时,它本应失败,但可能会成功。内部 ID: OTP-18692 辅助 ID: GH-7517, PR-7519
编译嵌套的
try
/catch
和catch
表达式可能会导致内部编译器错误。内部 ID: OTP-18701 辅助 ID: GH-7477, PR-7532
在复杂表达式中使用
bnot
运算符可能会导致编译器以内部一致性失败诊断终止。内部 ID: OTP-18719 辅助 ID: GH-7468, PR-7562
修复了导致编译器在二进制优化过程中崩溃的 bug。
内部 ID: OTP-18721 辅助 ID: PR-7527
当尝试编译一个不可能匹配的二进制模式时,编译器可能会以内部错误终止。
内部 ID: OTP-18725 辅助 ID: GH-7467
改进和新特性
修复了与别名优化过程相关的各种性能问题。
内部 ID: OTP-18691 辅助 ID: PR-7448
编译器 8.3.2
修复的 Bug 和故障
修复了一个类型处理 bug,该 bug 会导致正确代码出现内部一致性失败。
内部 ID: OTP-18625 辅助 ID: GH-7354
修复了一个可能导致
throw
异常的堆栈跟踪被错误优化的 bug。内部 ID: OTP-18626 辅助 ID: GH-7356
使用 '
or
' 的复杂保护表达式并非总是完全求值,导致本应失败的保护语句成功。内部 ID: OTP-18634 辅助 ID: GH-7370
编译器 8.3.1
修复的 Bug 和故障
修复了一个 bug,其中保护语句中失败的
bsl
表达式抛出一个异常而不是导致保护语句失败。内部 ID: OTP-18576
修复了一个会导致验证器拒绝合法代码的 bug。
内部 ID: OTP-18581 辅助 ID: GH-7251
编译器可以重新排序匹配二进制文件的子句,从而使不正确的子句匹配。这只可能发生在使用了选项
{error_location,line}
的代码中,或者发生在没有行号或列号信息的代码中(例如,由解析转换生成)。内部 ID: OTP-18583 辅助 ID: GH-7259
使用
or
运算符和可能失败的保护 BIF 的复杂保护表达式有时会被错误编译,从而即使对保护 BIF 的调用失败,保护也会成功。内部 ID: OTP-18593 辅助 ID: GH-7252
禁用优化后,
try
/catch
结构可能会返回不正确的值。内部 ID: OTP-18600 辅助 ID: GH-7248
在极少数情况下,二进制构建和
binary_part/3
的组合会导致编译器生成不安全的代码,从而导致运行时系统崩溃。内部 ID: OTP-18601
当编译带有多个用 '
or
' 或 ';
' 分隔的保护测试的保护语句时,编译器可能会非常慢。内部 ID: OTP-18617 辅助 ID: GH-7338
即使映射更新失败,使用 '
or
' 和映射更新的复杂保护表达式也可能会成功。内部 ID: OTP-18619 辅助 ID: GH-7339
编译器 8.3
修复的 Bug 和故障
编译器会默默接受联合类型中的单例(未绑定)类型变量。从 Erlang/OTP 26 开始,编译器将为此示例生成警告。可以使用
nowarn_singleton_typevar
选项禁用该警告。在 Erlang/OTP 27 中,该警告将变成一个错误。内部 ID: OTP-18389 辅助 ID: GH-6508, PR-6864, GH-7116
改进和新特性
优化了记录更新。
内部 ID: OTP-18126 辅助 ID: PR-6033
JIT 中有几个针对二进制语法的新的优化
- 优化了具有固定大小段的二进制文件的创建和匹配。
- 优化了 UTF-8 段的创建和匹配。
- 优化了附加到二进制文件的操作。
内部 ID: OTP-18137 辅助 ID: PR-6259, PR-6404, PR-6576, PR-6804
现在,当所有键都是在编译时已知的文字时,编译器和 JIT 会为小型映射的创建生成更好的代码。
内部 ID: OTP-18185 辅助 ID: GH-6139
二进制语法中的一个限制已移除。现在可以并行匹配二进制模式。示例:
<<A:8>> = <<B:4,C:4>> = Bin
内部 ID: OTP-18297 辅助 ID: GH-6348
文档中说明
$\^X
是 Control X 的 ASCII 代码,其中 X 是大写或小写字母。但是,此表示法适用于任何字符 X,即使它没有意义。在 Erlang/OTP 26 中,现在文档中说明以下字符也允许跟在
\^
字符之后:@
、[
、\
、]
、^
、_
和?
。尝试使用其他字符将被拒绝,并出现编译器错误。现在
$\^?
的值为 127(而不是早期版本中的 31)。自有 ID:OTP-18337 辅助 ID:GH-6477,PR-6503
现在允许在卫语句和匹配规范中使用 BIF
min/2
和max/2
。自有 ID:OTP-18367 辅助 ID:GH-6544
现已实现 EEP 58 中建议的映射推导式。
自有 ID:OTP-18413 辅助 ID:EEP-58,PR-6727
改进了选择性接收优化,现在可以为从其他函数返回的引用启用该优化。
这大大提高了
gen_server:send_request/3
、gen_server:wait_response/2
和类似函数的性能。自有 ID:OTP-18431 辅助 ID:PR-6739
弃用
dbg:stop_clear/0
,因为它只是dbg:stop/0
的函数别名。自有 ID:OTP-18478 辅助 ID:GH-6903
编译器现在将内联对
maps:get/3
的调用。自有 ID:OTP-18502
在 Erlang/OTP 27 中,
0.0
将不再被认为与-0.0
完全相等。请参阅 即将到来的潜在不兼容性。自有 ID:OTP-18574
编译器 8.2.6.4
修复的错误和故障
在极少数情况下,不安全的优化可能导致编译器为列表匹配生成不正确的代码。
内部 ID: OTP-19003 辅助 ID: GH-8187, PR-8189
在极少数情况下,编译器代码会为位语法匹配生成不安全的代码。
内部 ID: OTP-19019
编译器 8.2.6.3
修复的错误和故障
修复了一个可能导致
throw
异常的堆栈跟踪被错误优化的 bug。内部 ID: OTP-18626 辅助 ID: GH-7356
编译器 8.2.6.2
修复的错误和故障
当编译带有多个用 '
or
' 或 ';
' 分隔的保护测试的保护语句时,编译器可能会非常慢。内部 ID: OTP-18617 辅助 ID: GH-7338
编译器 8.2.6.1
修复的错误和故障
修复了一个 bug,其中保护语句中失败的
bsl
表达式抛出一个异常而不是导致保护语句失败。内部 ID: OTP-18576
使用
or
运算符和可能失败的保护 BIF 的复杂保护表达式有时会被错误编译,从而即使对保护 BIF 的调用失败,保护也会成功。内部 ID: OTP-18593 辅助 ID: GH-7252
编译器 8.2.6
修复的错误和故障
修复了可能导致编译器对正确的代码产生内部错误的类型处理错误。
自有 ID:OTP-18565 辅助 ID:GH-7147
编译器 8.2.5
修复的错误和故障
当本应抛出异常的映射更新(例如
#{}#{key:=value}
)未被使用时,异常会丢失。自有 ID:OTP-18497 辅助 ID:GH-6960,PR-6965
修复了验证器中导致其拒绝有效代码的错误。
自有 ID:OTP-18516 辅助 ID:GH-6969
编译器 8.2.4
修复的错误和故障
修复了会导致编译器挂起的错误。
自有 ID:OTP-18378 辅助 ID:GH-6604
修复了编译包含
maybe
表达式的代码时发生的崩溃。自有 ID:OTP-18381 辅助 ID:GH-6601
使用显式大小为
all
的二进制段构建二进制文件会导致编译器崩溃。自有 ID:OTP-18407 辅助 ID:GH-6707
编译器会为以下类型的表达式生成不正确的代码
Pattern = BoundVar1 = . . . = BoundVarN = Expression
如果任何绑定变量的值与
Expression
不同,则应引发异常。编译器会生成代码,无论值是否匹配,都会导致绑定变量绑定到Expression
的值。自有 ID:OTP-18470 辅助 ID:GH-6873,PR-6877
编译器 8.2.3
修复的错误和故障
修复了可能导致合法代码验证失败的错误。
自有 ID:OTP-18365
消除了
beam_types
模块中罕见的崩溃。自有 ID:OTP-18368
编译器 8.2.2
修复的错误和故障
对于大于 9999 的行号,编译器消息中的行号将被截断为 4 位数字。
自有 ID:OTP-18268 辅助 ID:GH-6332
在极少数情况下,将二进制文件作为
receive
子句的一部分进行匹配会导致编译器因内部一致性检查失败而终止。自有 ID:OTP-18273 辅助 ID:GH-6341
编译具有复杂位语法匹配的函数,例如
f(<<X:0, _:X>>, <<Y:0, _:Y>>) -> ok.
可能会导致编译器崩溃。自有 ID:OTP-18308 辅助 ID:GH-6426
不允许从卫语句中调用函数。当通过构造一个使用调用函数的默认初始化表达式的记录时,编译器未能拒绝卫语句中的调用。
自有 ID:OTP-18325 辅助 ID:GH-6465,GH-6466
当使用具有复杂字段初始化表达式的记录作为列表推导式中的过滤器时,编译器可能会崩溃。
自有 ID:OTP-18336 辅助 ID:GH-6501,PR-6502
编译器 8.2.1
修复的错误和故障
编译器现在将禁止使用空原子
''
作为模块名称。同样禁止包含控制字符的模块名称,以及仅包含空格和软连字符的模块名称。自有 ID:OTP-18125 辅助 ID:GH-6026
当尝试编译没有位置信息的生成代码时,
bin_opt_info
和recv_opt_info
选项会导致编译器崩溃。自有 ID:OTP-18162 辅助 ID:PR-6102
在涉及浮点运算的极少数情况下,编译器可能会因内部一致性检查失败而终止。
自有 ID:OTP-18182 辅助 ID:GH-6163
在对非数字执行算术指令的极少数情况下,编译器可能会崩溃。
自有 ID:OTP-18183 辅助 ID:GH-6169
在极少数情况下,嵌套案例中的复杂布尔表达式可能会导致编译器崩溃。
自有 ID:OTP-18184 辅助 ID:GH-6164
类似于
#{assoc:=V} = #key=>self()}, V
的表达式将返回空映射而不是引发异常。自有 ID:OTP-18186
消除了编译复杂卫语句时编译器
beam_ssa_bool
传递中的崩溃。自有 ID:OTP-18187 辅助 ID:GH-6184
在极少数情况下,编译器可能会因内部一致性检查失败而崩溃。
自有 ID:OTP-18202 辅助 ID:GH-6222
当使用
inline_list_funcs
选项进行编译时,编译器可能会产生无意义的警告。自有 ID:OTP-18214 辅助 ID:GH-6158
当给定
no_ssa_opt
选项时,编译器在编译映射匹配时可能会因内部一致性失败诊断而终止。自有 ID:OTP-18234 辅助 ID:GH-6277
改进和新功能
通过不对带引号的原子发出警告,使现有原子在实验性功能中作为关键字的警告更加精确。
自有 ID:OTP-18050
有一个新的配置选项
--enable-deterministic-build
,它将在构建 Erlang/OTP 时应用deterministic
编译器选项。deterministic
选项已得到改进,以消除多个应用程序中更多的非确定性来源。自有 ID:OTP-18165 辅助 ID:PR-5965
编译器 8.2
修复的错误和故障
已纠正一个关于变量作用域的细微错误。请考虑以下示例
(A=1) + fun() -> A = 2() end
在 shell 中,该表达式正确计算为
3
。在编译的代码中,它引发{badmatch, 2}
异常。自有 ID:OTP-17810 辅助 ID:GH-5379
修复了类型优化期间会导致编译器崩溃的罕见错误。
自有 ID:OTP-17820
从 OTP 24 开始,当创建一个 fun 并立即使用时,它将被内联。内联的一个意外后果是,在没有内联的情况下将是
function_clause
异常的内容现在将是一个令人困惑的case_clause
异常。这已得到纠正,因此function_clause
异常在内联代码中仍然是function_clause
异常。自有 ID:OTP-17860 辅助 ID:GH-5513,OTP-17226
如果即使所有记录字段都已显式初始化,也使用了默认记录字段初始化 (
_ = Expr
),则不会评估Expr
。这本来不是问题,除非Expr
会绑定一个随后使用的变量,在这种情况下,编译器会崩溃。例如,如果记录
#r{}
被定义为只有一个字段a
,则以下代码会导致编译器崩溃#r{a=[],_=V=42}, V
为了解决这个问题,编译器将确保
Expr
始终至少评估一次。编译器现在会将示例重写为本质上的V=42, #r{a=[]}, V
自有 ID:OTP-18083
改进和新功能
为了启用更多优化,使用 OTP 21 及更早版本编译的 BEAM 文件无法在 OTP 25 中加载。
自有 ID:OTP-16702
添加了对编译属性
-nifs()
的支持,以使编译器和加载器能够了解哪些函数可能会被erlang:load_nif/2
覆盖为 NIF。建议在所有加载 NIF 库的模块中使用此属性。自有 ID:OTP-17151 辅助 ID:ERIERL-590,PR-5479
当使用二进制语法构建二进制文件失败时,在 shell 中以及由
erl_error:format_exception/3,4
打印的错误消息将包含有关哪里出错的更多详细信息。自有 ID:OTP-17504 辅助 ID:GH-4971,PR-5281,PR-5752
Erlang 编译器现在在 BEAM 文件中包含类型信息,并且 JIT 现在可以使用该类型信息来进行优化,例如消除或简化类型测试。
自有 ID:OTP-17684 辅助 ID:PR-5316,PR-5664
改进了 JIT 对
perf
和gdb
等外部工具的支持,允许它们显示行号,甚至在可以找到时显示原始 Erlang 源代码。为了帮助他们找到源代码,添加了
absolute_path
编译器选项以嵌入模块的绝对文件路径。自有 ID:OTP-17685
已实现 EEP-49 中提出的
maybe
...end
结构。它可以简化复杂的代码,否则这些代码需要使用深度嵌套的 case 语句。要启用
maybe
,请向erlc
提供选项-enable-feature maybe_expr
,或在模块内添加-feature(maybe_expr, enable).
。自有 ID:OTP-17705 辅助 ID:PR-5411
当记录匹配或记录更新失败时,会引发
{badrecord,ExpectedRecordTag}
异常。在此版本中,异常已更改为{badrecord,ActualValue}
,其中ActualValue
是实际找到的值,而不是预期的记录。自有 ID:OTP-17841 辅助 ID:PR-5694
改进了 try/catch 表达式的优化。
自有 ID:OTP-17842
编译器的
beam_trim
过程对于巨大的直线型函数来说可能非常慢。现在,它将更快地编译此类函数(对于某些大型函数,从几分钟缩短到几秒钟)。自有 ID:OTP-17885 辅助 ID:GH-5140
添加了对 EEP-60 中描述的可配置功能的支持。可以在编译期间使用
erlc
的选项(-enable-feature Feature
、-disable-feature Feature
和+{feature, Feature, enable|disable}
)以及文件中的指令(-feature(Feature, enable|disable).
)启用/禁用功能。类似的选项可用于erl
以启用/禁用运行时允许的功能。新的maybe
表达式(EEP-49)完全支持作为maybe_expr
功能。该功能支持已在参考手册中记录。自有 ID:OTP-17988
编译器 8.1.1.6
修复的错误和故障
在极少数情况下,不安全的优化可能导致编译器为列表匹配生成不正确的代码。
内部 ID: OTP-19003 辅助 ID: GH-8187, PR-8189
在极少数情况下,编译器代码会为位语法匹配生成不安全的代码。
内部 ID: OTP-19019
编译器 8.1.1.5
修复的错误和故障
当编译带有多个用 '
or
' 或 ';
' 分隔的保护测试的保护语句时,编译器可能会非常慢。内部 ID: OTP-18617 辅助 ID: GH-7338
编译器 8.1.1.4
修复的错误和故障
使用
or
运算符和可能失败的保护 BIF 的复杂保护表达式有时会被错误编译,从而即使对保护 BIF 的调用失败,保护也会成功。内部 ID: OTP-18593 辅助 ID: GH-7252
编译器 8.1.1.3
修复的错误和故障
编译器会为以下类型的表达式生成不正确的代码
Pattern = BoundVar1 = . . . = BoundVarN = Expression
如果任何绑定变量的值与
Expression
不同,则应引发异常。编译器会生成代码,无论值是否匹配,都会导致绑定变量绑定到Expression
的值。自有 ID:OTP-18470 辅助 ID:GH-6873,PR-6877
编译器 8.1.1.2
修复的错误和故障
不允许从卫语句中调用函数。当通过构造一个使用调用函数的默认初始化表达式的记录时,编译器未能拒绝卫语句中的调用。
自有 ID:OTP-18325 辅助 ID:GH-6465,GH-6466
修复了可能导致合法代码验证失败的错误。
自有 ID:OTP-18365
编译器 8.1.1.1
修复的错误和故障
当尝试编译没有位置信息的生成代码时,
bin_opt_info
和recv_opt_info
选项会导致编译器崩溃。自有 ID:OTP-18162 辅助 ID:PR-6102
在涉及浮点运算的极少数情况下,编译器可能会因内部一致性检查失败而终止。
自有 ID:OTP-18182 辅助 ID:GH-6163
编译器 8.1.1
修复的错误和故障
修复了验证器中的一个性能错误,该错误导致某些文件需要很长时间才能编译。
自有 ID:OTP-18066 辅助 ID:GH-5915
在极少数情况下,编译器会错误地假设对
setelement/3
的调用总是会失败,并删除该调用之后的所有代码。自有 ID:OTP-18082
编译器 8.1
修复的错误和故障
表达式
<<0/native-float>>=Bin
总是会匹配失败,而<<0/float-native>>=Bin
会匹配成功(前提是Bin
包含0.0
的二进制表示形式)。自有 ID:OTP-17895
改进和新功能
现在,编译器将更快地编译具有直线代码的巨型函数。
自有 ID:OTP-17886 辅助 ID:GH-5140, GH-5686
编译器 8.0.4
修复的错误和故障
当 Dialyzer 调用编译器时,它将不再应用二进制模式的优化,该优化会将模式
<<"bar">>
转换为<<6447474:24>>
,这在 Dialyzer 输出时会非常令人困惑。自有 ID:OTP-17768 辅助 ID:GH-5429
编译器会用对
error(badarg)
的调用替换已知失败的调用(例如atom_to_list(42)
)。使用 OTP 24 (EEP 54) 中引入的扩展错误信息,那些“优化”的调用将不包含扩展错误信息。为了确保尽可能多的扩展错误信息可用,编译器现在会保留原始调用,即使已知该调用会失败。自有 ID:OTP-17786 辅助 ID:GH-5440
编译器 8.0.3
修复的错误和故障
如果解析转换使用
throw/1
或exit/1
引发异常,则编译器会将其报告为内部编译器错误,这会令人困惑。已修正为报告解析转换失败。自有 ID:OTP-17421
失败的调用
io:format("~p\n")
将导致第 0 行的警告,而不是正确的行号和列号。此问题已得到纠正,并且所有针对io:format()
失败调用的警告都已重新措辞,以使其更清楚地说明问题所在。自有 ID:OTP-17430
当给出选项
warn_missing_spec
和export_all
时,只会为使用-export
属性显式导出的函数提供缺少规范的警告。自有 ID:OTP-17434 辅助 ID:GH-4772
在极少数情况下,编译器可能会为已构造但从未使用过的项发出不正确的警告。
自有 ID:OTP-17446 辅助 ID:PR-4899
修复了即使给出了
deterministic
选项,构建也不可重现的错误。特别是,具有超过 32 个元素的 map 字面量的模块可能会导致此问题。作为此修复的一部分,
term_to_binary
BIF 现在接受选项deterministic
。自有 ID:OTP-17495 辅助 ID:PR-5153
MODULE
和MODULE_STRING
宏似乎总是已定义(当由-ifdef
测试时),即使尚未看到任何-module()
声明。已更改,以便如果之前未看到-module()
,则-ifdef ?MODULE.
不会将 ?MODULE 视为已定义。自有 ID:OTP-17505 辅助 ID:GH-4995
在 guard 中,对于
X
的非布尔值,not (X =:= true)
会错误地评估为false
。自有 ID:OTP-17510 辅助 ID:GH-5007
当向编译器提供
deterministic
选项时,?FILE
宏会在第一个include
指令之前扩展到源文件的完整路径,并在include
指令之后扩展到文件名的基本部分。自有 ID:OTP-17581 辅助 ID:PR-5141
编译器 8.0.2
修复的错误和故障
当使用
throw/1
时,编译器优化过程可能会在给定奇怪但合法的代码时崩溃。自有 ID:OTP-17489 辅助 ID:GH-4953
编译器 8.0.1
修复的错误和故障
修复了一个错误,该错误可能导致在使用 catch 块中的
erlang:raise/3
时忽略after
块。自有 ID:OTP-17428 辅助 ID:GH-4859
修复了验证过程中的一个错误,该错误可能导致其拒绝有效代码。
自有 ID:OTP-17437 辅助 ID:OTP-17357, GH-4774
编译器 8.0
修复的错误和故障
浮点零 (0.0) 可以是正 (+0.0) 和负 (-0.0)。编译器、运行时系统和 STDLIB 中已修复多个错误,以确保 0.0 上的负号不会丢失。
自有 ID:OTP-17077 辅助 ID:ERL-1431, PR-2903, PR-2905, PR-2906
一个在 try/catch 中重复的堆栈跟踪变量未被拒绝。以下示例现在将导致编译错误
try E catch _:A:A -> A end.
自有 ID:OTP-17104 辅助 ID:ERL-1380
当使用
-MMD
选项同时生成依赖文件和 BEAM 文件时,消除了 Dialyzer 崩溃的问题。自有 ID:OTP-17118 辅助 ID:PR-2825
当给出
makedep
选项时,如果依赖项输出包含非 latin1 字符,编译器将崩溃。现在,编译器将输出以 UTF-8 编码的依赖项信息,以避免崩溃。自有 ID:OTP-17206
改进和新功能
选择性接收优化现在将更频繁地应用。
新的
recv_opt_info
编译标志可用于打印与此优化相关的诊断信息。您可以在效率指南中阅读更多关于选择性接收优化的信息。
自有 ID:OTP-10391 辅助 ID:OTP-16226
当我们证明
erlang:throw/1
永远不会被检查时,它将不再构建堆栈跟踪。自有 ID:OTP-16334
在关键字“try”和“of”之间绑定的变量现在可以在“of”关键字之后的子句中使用(即,在没有引发异常的成功情况下)。
自有 ID:OTP-16706 辅助 ID:ERL-1281
现在,编译器警告和错误除了行号之外,还包括列号。
当编译器发出消息时,会打印源代码行,并附带一个标记(一个
^
字符)来指示问题所在的列位置。选项 'brief
' 会移除源代码行的打印输出。已添加编译器选项
{error_location, line | column}
。默认值为column
。除了向编译警告和错误添加列号外,该选项还确定抽象代码中是否包含列号。如果工具停止工作,设置环境变量ERL_COMPILER_OPTIONS
可以提供帮助(包括{error_location, line}
)。编译器现在会调用解析转换中的函数
PT
:parse_transform_info/0
(如果存在)。解析转换可以使用它来表明它们只能处理抽象代码中的行号。*潜在不兼容性*
Own Id: OTP-16824 Aux Id: PR-2664, PR-3006
修复了一个性能错误,该错误导致包含大量
try/after
块的函数编译速度缓慢。Own Id: OTP-16867 Aux Id: ERL-1354
已删除实验性的 HiPE 应用程序,以及其他应用程序中的所有相关功能。
*潜在不兼容性*
Own Id: OTP-16963
列表和二进制推导式中的生成器如果类型不正确,现在会引发
{bad_generator,Generator}
异常(而不是引发临时的badarg
或badarih
异常)。类似地,当过滤器未计算为布尔值时,将引发{bad_filter,Filter}
异常。还修复了二进制推导式编译中的一些小错误。Own Id: OTP-16964
某些编译器警告(例如,对于结果被忽略的表达式的警告)不能通过赋值给以 '
_
' 开头的变量来抑制,而只能通过赋值给匿名变量('_
')来抑制。现在已更改为,任何可以通过赋值给匿名变量来抑制的警告,也可以通过赋值给以 '_
' 开头的变量来抑制。Own Id: OTP-16981 Aux Id: ERL-1113
先前未记录的编译器选项
warn_missing_spec
和warn_missing_spec_all
现在已记录在案。Own Id: OTP-17078 Aux Id: ERL-1430, PR-2918
当匹配(先前绑定的)以下划线开头的变量时,编译器现在会发出警告。
Own Id: OTP-17123
除非包含“coding: latin-1”注释,否则编译器将不再接受非 utf-8 编码的 Erlang 源文件。
Own Id: OTP-17168
添加了新的编译器选项
from_abstr
和no_lint
。它们在实现运行在 BEAM 上的其他语言时很有用。Own Id: OTP-17172
位匹配和构造语法现在支持 16 位浮点数 (IEEE 754-2008)。
Own Id: OTP-17207
编译器现在会内联仅在其定义后立即使用一次的 fun。
Own Id: OTP-17226 Aux Id: GH-4019, PR-4545
现在可以使用新的选项
nowarn_opportunistic
、nowarn_nomatch
、nowarn_ignored
和nowarn_failed
来禁用编译器优化过程中发出的警告。Own Id: OTP-17260
引入新类型
nonempty_binary/0
和nonempty_bitstring/0
。Own Id: OTP-17301 Aux Id: GH-4636
添加编译器选项
{nowarn_unused_record, RecordNames}
。记录编译器选项nowarn_unused_type
。Own Id: OTP-17330
编译器 7.6.9.3
修复的错误和故障
不允许从卫语句中调用函数。当通过构造一个使用调用函数的默认初始化表达式的记录时,编译器未能拒绝卫语句中的调用。
自有 ID:OTP-18325 辅助 ID:GH-6465,GH-6466
修复了可能导致合法代码验证失败的错误。
自有 ID:OTP-18365
编译器会为以下类型的表达式生成不正确的代码
Pattern = BoundVar1 = . . . = BoundVarN = Expression
如果任何绑定变量的值与
Expression
不同,则应引发异常。编译器会生成代码,无论值是否匹配,都会导致绑定变量绑定到Expression
的值。自有 ID:OTP-18470 辅助 ID:GH-6873,PR-6877
编译器 7.6.9.2
修复的错误和故障
在极少数情况下,编译器会错误地假设对
setelement/3
的调用总是会失败,并删除该调用之后的所有代码。自有 ID:OTP-18082
编译器 7.6.9.1
修复的错误和故障
修复了验证过程中的一个错误,该错误可能导致其拒绝有效代码。
自有 ID:OTP-17437 辅助 ID:OTP-17357, GH-4774
编译器 7.6.9
修复的错误和故障
恢复了对
OTP-17357
的修复,因为它被证明是不完整的,并且使验证器拒绝比以前更多的合法代码。它将在稍后的补丁中进行更彻底的修复。
Own Id: OTP-17386 Aux Id: ERIERL-650, OTP-17357
编译器 7.6.8
修复的错误和故障
修复了验证器中可能导致其拒绝有效代码的错误。
Own Id: OTP-17357 Aux Id: GH-4774
编译器 7.6.7
修复的错误和故障
修复了类型优化过程中可能产生不正确的值或导致执行错误子句的错误。
Own Id: OTP-17073
修复了验证器中可能导致其拒绝有效代码的错误。
Own Id: OTP-17126 Aux Id: ERL-1471
编译器 7.6.6
修复的错误和故障
修复了几个小的编译器错误
使用列表作为二进制段的大小来构造二进制文件可能会生成无法加载的 BEAM 文件。
当匹配类型为
float
的二进制段并忽略匹配出的值时,即使大小无效或浮点数的值为 NaN 或其他非数字浮点值,匹配也总是会成功。尝试构造无效的外部 fun(例如,
fun m:f:bad
)应该引发 'badarg
' 异常,但如果该值从未使用过,则不会引发异常。Own Id: OTP-16932
修复了验证器中可能导致其拒绝有效代码的多个错误。
Own Id: OTP-17039 Aux Id: ERL-1426
当二进制推导式具有依赖于另一个生成器的生成器时,编译器可能会崩溃。
Own Id: OTP-17045 Aux Id: ERL-1427
修复了类型优化过程中可能产生不正确的值或导致执行错误子句的错误。
Own Id: OTP-17072 Aux Id: ERL-1440
编译器 7.6.5
修复的错误和故障
修复了布尔值优化过程中导致编译器混淆不同子句的错误。
Own Id: OTP-16951 Aux Id: ERL-1384
编译器 7.6.4
修复的错误和故障
修复了在非常大的函数中由元组匹配触发的性能错误。
Own Id: OTP-16895 Aux Id: ERL-1359
编译器 7.6.3
修复的错误和故障
如果使用 '
Map#{Key := Value}
' 语法更新映射失败,则堆栈回溯中的行号可能不正确。Own Id: OTP-16701 Aux Id: ERL-1271
修复了降低具有深度嵌套术语的模块编译速度的性能错误。
Own Id: OTP-16755 Aux Id: ERL-1297
在极少数情况下,编译器可能会执行不安全的优化,这会导致嵌套映射模式匹配失败。
Own Id: OTP-16820
修复了验证器中导致其拒绝有效代码的错误。
Own Id: OTP-16838 Aux Id: ERL-1340
编译器 7.6.2
修复的错误和故障
当重复调用
is_map_key
时,编译器可能会因内部一致性失败而终止。Own Id: OTP-16708 Aux Id: ERL-1276
修复了类型推断过程中可能导致编译器挂起的错误。
Own Id: OTP-16745 Aux Id: ERL-1289
编译器 7.6.1
修复的错误和故障
在极少数情况下,使用 'not' 的保护可能会计算为错误的布尔值。
Own Id: OTP-16652 Aux Id: ERL-1246
引用绑定到布尔表达式的变量的保护表达式可能会计算为错误的值。
Own Id: OTP-16657 Aux Id: ERL-1253
编译器 7.6
修复的错误和故障
erlang:fun_info(fun foo/1, name/1)
过去返回的函数名称基于使用fun foo/1
的函数名称。现在返回的名称是-fun.foo/1-
。Own Id: OTP-15837
如果受影响的字段数为零,则不再允许使用
_
初始化记录字段。Own Id: OTP-16516
改进和新功能
已实现 EEP-52。
在二进制匹配中,现在允许要匹配的段的大小是保护表达式,类似地,在映射匹配中,键现在可以是保护表达式。有关更多详细信息,请参阅 Erlang 参考手册和编程示例。
生成 Core Erlang 代码的语言编译器或代码生成器可能需要更新以与 OTP 23 中的编译器兼容。有关更多详细信息,请参阅 EEP 52 中的向后兼容性部分。
Own Id: OTP-14708
允许在数字字面量中使用下划线以提高可读性。例如:
123_456_789
,16#1234_ABCD
。自有 ID:OTP-16007 辅助 ID:PR-2324
改进了类型优化过程对依赖自身的类型的推断,从而使我们能够获得更准确的类型并跟踪列表的内容类型。
自有 ID:OTP-16214 辅助 ID:PR-2460
支持对新的
spawn_request()
BIF 返回的引用进行消息队列优化。自有 ID:OTP-16367 辅助 ID:OTP-15251
现在,当在加载 NIF 的模块中使用内联时,编译器将发出警告。
自有 ID:OTP-16429 辅助 ID:ERL-303
重构了已弃用和已删除函数的内部处理方式。
自有 ID:OTP-16469
浮点数学异常的行信息有时不正确。
自有 ID:OTP-16505 辅助 ID:ERL-1178
现在可以在
-compile()
属性中指定debug_info
选项。自有 ID:OTP-16523 辅助 ID:ERL-1058
减少了并行构建(例如
make -j128
)中erlc
的资源使用。自有 ID:OTP-16543 辅助 ID:ERL-1186
编译器 7.5.4.3
改进和新功能
修复了类型优化过程中可能产生不正确的值或导致执行错误子句的错误。
Own Id: OTP-17073
编译器 7.5.4.2
已修复的错误和故障
修复了验证器中的一个错误,该错误可能导致它拒绝有效的代码
Own Id: OTP-17039 Aux Id: ERL-1426
编译器 7.5.4.1
已修复的错误和故障
修复了一个可能导致编译器在构造二进制文件的代码上崩溃的错误。
自有 ID:OTP-16747 辅助 ID:ERL-1290
编译器 7.5.4
已修复的错误和故障
修复了验证器中可能导致其拒绝有效代码的错误。
自有 ID:OTP-16580 辅助 ID:ERL-1212
编译器 7.5.3
已修复的错误和故障
带有“
after 0
”子句的“receive
”会阻止在匹配新创建的引用时可以避免扫描整个接收队列的优化。自有 ID:OTP-16350
HiPE 可以再次处理带有
catch
和try
结构的模块。自有 ID:OTP-16418
修复了位语法优化中可能导致编译器崩溃的错误。
自有 ID:OTP-16515
编译器 7.5.2
已修复的错误和故障
修复了一个可能导致编译器拒绝使用
is_map_key/2
BIF 的有效代码的错误。自有 ID:OTP-16452 辅助 ID:ERL-1161
修复了一个可能导致编译器拒绝多次匹配同一个映射键的有效代码的错误。
自有 ID:OTP-16456 辅助 ID:ERL-1163
编译复杂的
receive
语句时,编译器可能会崩溃。自有 ID:OTP-16466 辅助 ID:ERL-1170
当创建但从未使用 fun 时,编译器可能会崩溃。
编译表达式
true = 0 / X
时,编译器可能会崩溃。自有 ID:OTP-16467 辅助 ID:ERL-1166, ERL-1167
编译器 7.5.1
已修复的错误和故障
修复了编译器中可能导致它拒绝有效代码的错误。
自有 ID:OTP-16385 辅助 ID:ERL-1128
编译器 7.5
已修复的错误和故障
修复了 linter 中的一个错误,该错误会导致列表和二进制推导式抑制不安全的变量错误。
自有 ID:OTP-16053 辅助 ID:ERL-1039
当从 Core Erlang 代码开始编译时,将始终运行
core_lint
传递,并且如果发现任何错误,则会中止编译。自有 ID:OTP-16181 辅助 ID:ERL-1065
改进和新功能
当编译器检测到没有编码字符串的非 utf-8 编码的源文件时,出现的警告消息已更改为包含有关对没有编码字符串的 latin1 编码的源文件的支持将在 Erlang/OTP 24 中删除的信息。
自有 ID:OTP-16054 辅助 ID:OTP-11791
编译器 7.4.9
已修复的错误和故障
修复了一个性能错误,该错误导致重复匹配大型记录需要很长时间才能编译。
自有 ID:OTP-16259 辅助 ID:ERIERL-436
编译器 7.4.8
已修复的错误和故障
编译器可能会对接收执行不安全的优化,这会导致接收仅扫描部分消息队列。
编译器中的此错误修复修复了套接字模块中的一个错误。
自有 ID:OTP-16219 辅助 ID:ERL-1076
编译器 7.4.7
已修复的错误和故障
修复了编译器可能为 '
try
' 内的 'receive
' 语句生成不正确代码的错误。自有 ID:OTP-16199
编译器 7.4.6
已修复的错误和故障
修复了位语法优化中可能导致编译器崩溃的错误。
自有 ID:OTP-16103 辅助 ID:ERL-1050
编译器 7.4.5
已修复的错误和故障
以下代码会在 OTP 22 中导致编译器崩溃:
[some_atom = fun some_function/1]
自有 ID:OTP-15833
编译大型函数时,编译速度可能会变得非常慢(以分钟而不是秒为单位)。(感谢 Kostis Sagonas 报告此错误。)
自有 ID:OTP-15923
修复了验证器中可能拒绝有效代码的错误。
自有 ID:OTP-15954 辅助 ID:ERL-995
在极少数情况下,当两个子句具有相同的主体和测试单个布尔变量的保护测试时,可以丢弃第二个子句的保护测试,如果在未执行第一个子句的情况下无条件执行第二个子句。
自有 ID:OTP-15963
修复了主要执行模式匹配的大型函数的编译速度极慢的问题。
自有 ID:OTP-15966 辅助 ID:ERL-1014
编译器可能会为映射模式匹配生成不安全的代码(这会导致运行时系统崩溃)。如果在运行时映射中不存在匹配的键,则该代码可能不安全。
自有 ID:OTP-15968 辅助 ID:ERL-1017
使用“
no_type_opt
”选项时,使用 try/after 的正确代码可能无法编译。自有 ID:OTP-15969 辅助 ID:ERL-997
当编译对使用二进制语法提取的二进制文件调用“
length/1
”的代码时,编译器可能会崩溃。自有 ID:OTP-15970 辅助 ID:ERL-1013
修复了编译器在编译 receive 语句时可能会因内部一致性失败错误而失败的错误。
自有 ID:OTP-15982 辅助 ID:ERL-1022
修复了在函数头中编译二进制匹配时编译器会崩溃的问题。
自有 ID:OTP-15985 辅助 ID:ERL-1026
编译器 7.4.4
已修复的错误和故障
修复了在
22.0.6
(OTP-15952) 中引入的编译器崩溃问题。自有 ID:OTP-15953 辅助 ID:ERL-999
编译器 7.4.3
已修复的错误和故障
修复了在保护之外匹配
tuple_size/1
时的不安全优化,如果参数不是元组,则可能会导致仿真器崩溃。自有 ID:OTP-15945
修复了一个罕见的错误,该错误可能导致在匹配位串的函数中 BIF 失败时抛出错误的异常。
自有 ID:OTP-15946
修复了 try/catch 块内的 receive 语句可能会返回不正确结果的错误。
自有 ID:OTP-15952
编译器 7.4.2
修复的缺陷和故障
修复了构造二进制文件的不正确的类型判断,这可能导致
is_binary
检查在不应该成功时成功。自有 ID: OTP-15872
编译器 7.4.1
修复的缺陷和故障
当分析具有可变位置的
setelement/3
调用时,编译器的类型优化过程可能会挂起或循环很长时间。自有 ID: OTP-15828 辅助 ID: ERL-948
某些复杂的 receive 语句会导致内部编译器故障。
自有 ID: OTP-15832 辅助 ID: ERL-950
修复了一个不安全的类型优化。
自有 ID: OTP-15838
修复了优化编译器生成的异常(如 badmatch)时发生的崩溃,该异常的错误项是构造的二进制文件。
自有 ID: OTP-15839 辅助 ID: ERL-954
修复了与
++/2
运算符相关的不良优化,其中编译器假设它始终生成列表([] ++ RHS
返回RHS
原样,即使它不是列表)。自有 ID: OTP-15841
由于不安全的优化,
is_binary/1
测试后跟is_bitstring/1
(反之亦然)可能会失败。自有 ID: OTP-15845
Core Erlang 模块中,
case
中的最后一个子句匹配 map 将无法加载。自有 ID: OTP-15846 辅助 ID: ERL-955
修复了在编译复杂的嵌套 case 表达式时可能导致编译器崩溃的错误。
自有 ID: OTP-15848 辅助 ID: ERL-956
编译器 7.4
修复的缺陷和故障
record_info/2
是一个伪函数,需要在编译时已知的字面参数。因此,以下用法是非法的:fun record/info/2
。编译器在编译此类代码时会崩溃。已更正为发出编译错误。自有 ID: OTP-15760 辅助 ID: ERL-907
改进和新功能
编译器已重写为在内部使用基于静态单赋值 (SSA) 的中间表示。新的中间表示使更多的优化成为可能。
最明显的是,二进制匹配优化现在比以前适用于更多的情况。
另一个明显的改变是类型优化现在应用于本地函数调用,并且将比以前删除更多冗余的类型测试。
自有 ID: OTP-14894 辅助 ID: ERL-714
当 fun 仅在本地使用时,不再创建 fun,这大大提高了命名 fun 和“fun 包裹”宏的性能。
自有 ID: OTP-15273 辅助 ID: ERL-639
现在,所有可以在源文件中给出的编译器选项也可以在选项列表中给出,或者从
erlc
的命令行给出。具体而言,选项
{nowarn_deprecated_function,MFAs}
仅在文件中使用属性-compile()
时才被识别。选项{nowarn_unused_function,FAs}
的文档错误地说明仅在文件中起作用,但它在选项列表中给出时也起作用。自有 ID: OTP-15456
不允许对其他模块中的函数使用函数规范。
*潜在不兼容性*
自有 ID: OTP-15563 辅助 ID: ERL-845, OTP-15562
内部文档现已添加到 Erts 和 Compiler 应用程序中。
Erts 的内部文档描述了各种有趣的实现细节。这些细节可以随时更改。
Compiler 的内部文档记录了 Core Erlang 模块的 API。虽然我们不会无缘无故地更改这些 API,但我们不会像 OTP 中其余的 API 那样提供关于向后兼容性的相同保证。
自有 ID: OTP-15715
有新的编译器选项
nowarn_removed
和{nowarn_removed,Items}
来禁止对已从 OTP 中删除的函数和模块发出警告。自有 ID: OTP-15749 辅助 ID: ERL-904
编译器 7.3.2
修复的缺陷和故障
诸如
(A / B) band 16#ff
之类的表达式会导致编译器崩溃。自有 ID: OTP-15518 辅助 ID: ERL-829
给出
tuple_calls
选项时,可能会出现不正确的警告。生成的代码将是正确的。以下是触发警告的代码示例(list_to_atom("prefix_" ++ atom_to_list(suffix))):doit(X)
.自有 ID: OTP-15552 辅助 ID: ERL-838
(再次)优化 Dialyzer 对 guard 中
andalso
和orelse
的左结合用法的处理。自有 ID: OTP-15577 辅助 ID: ERL-851, PR-2141, PR-1944
编译器 7.3.1
修复的缺陷和故障
在 OTP 21 中引入了一项优化,避免为某些
case
表达式分配堆栈帧。(ERL-504/OTP-14808)事实证明,在极少数情况下,此优化是不安全的。因此,此优化已禁用。类似的优化将以安全的方式包含在 OTP 22 中。
自有 ID: OTP-15501 辅助 ID: ERL-807, ERL-514, OTP-14808
编译器 7.3
修复的缺陷和故障
修复了由于
beam_jump
传递中的错误导致的罕见的内部一致性故障。(感谢 Simon Cornish 报告此错误。)自有 ID: OTP-15400 辅助 ID: ERL-759
当编译使用
is_function/2
BIF 的代码时,编译器可能会因内部一致性检查失败而失败。自有 ID: OTP-15435 辅助 ID: ERL-778
当使用外部 fun 时,可以禁止对未使用的变量发出警告。
自有 ID: OTP-15437 辅助 ID: ERL-762
当编译调用
erlang:raise/3
的after
块(例如:erlang:raise(Class, Stacktrace, Stacktrace)
)时,编译器会崩溃自有 ID: OTP-15481
改进和新功能
指定时,
+{source,Name}
选项现在将覆盖堆栈跟踪中的实际文件名,而不是仅影响Mod:module_info()
的返回值。+deterministic
标志现在也会影响堆栈跟踪,省略除文件名之外的所有路径信息,修复了一个长期存在的问题,即确定性构建需要确定性路径。自有 ID: OTP-15245 辅助 ID: ERL-706
编译器 7.2.7
修复的缺陷和故障
修复了二进制匹配 guard 后生成不正确代码的错误。
自有 ID: OTP-15353 辅助 ID: ERL-753
编译器 7.2.6
修复的缺陷和故障
在极少数情况下,二进制匹配出的尾部可能是整个原始二进制文件。(在编译器应用程序的 7.2.5 版本中对此问题进行了部分更正。)
自有 ID: OTP-15335 辅助 ID: ERL-689, OTP-15219
编译器 7.2.5
修复的缺陷和故障
修复了阻止编译某些可变大小的二进制推导的错误。
自有 ID: OTP-15186 辅助 ID: ERL-665
从 Core Erlang 编译时,在某些仅用于其副作用的表达式中创建的 fun 会被巧妙地破坏。
自有 ID: OTP-15188 辅助 ID: ERL-658
当
receive
嵌套在try
/catch
中时,可能会出现内部一致性故障。自有 ID: OTP-15218 辅助 ID: ERL-684
在极少数情况下,二进制匹配出的尾部可能是整个原始二进制文件。
自有 ID: OTP-15219 辅助 ID: ERL-689
当
is_map_key/2
与not/1
或or/2
运算符一起在 guard 中使用时,当is_map_key/2
被传递一个非 map 作为第二个参数时,错误行为可能是错误的。在极少数情况下,编译使用
is_map_key/2
的代码可能会导致内部一致性检查失败。自有 ID: OTP-15227 辅助 ID: ERL-699
当编译在多个子句中具有多个接收的函数时,编译器可能会崩溃。
自有 ID: OTP-15235 辅助 ID: ERL-703
编译器 7.2.4
修复的缺陷和故障
修复了 OTP-15204 中的一个回归,该回归删除了某些外部构建工具所依赖的
.beam
文件元数据。自有 ID: OTP-15292
编译器 7.2.3
修复的缺陷和故障
修复了使用
+deterministic
选项编译的文件如果它们在不同的目录中编译但其他方面相同则不同的问题。自有 ID: OTP-15204 辅助 ID: ERL-679
编译器 7.2.2
修复的缺陷和故障
在极少数涉及匹配二进制文字字符串的情况下,编译器可能会优化掉应该执行的代码。
自有 ID: OTP-15156 辅助 ID: ERL-655
当编译调用
map_get(Key, Map)
然后更新同一个 map 的代码时,可能会出现内部一致性检查失败。自有 ID: OTP-15157
在极少数情况下,当编译浮点运算时,编译器可能会在
beam_jump
中崩溃。自有 ID:OTP-15166 辅助 ID:ERL-660
编译器 7.2.1
已修复的错误和故障
当编译使用了二进制语法的复杂函数时,可能会发生崩溃。
自有 ID:OTP-15150 辅助 ID:ERL-650
编译器 7.2
已修复的错误和故障
修复了导致不可能的元组匹配的优化过程中的错误。
自有 ID:OTP-14855 辅助 ID:ERL-549
当列表推导式被赋予非列表项时抛出的异常并不总是正确的。
自有 ID:OTP-14992 辅助 ID:ERL-572
当使用
[{inline,F/A}]
选项时,编译器在极少数情况下可能会产生不正确的代码。自有 ID:OTP-15115 辅助 ID:PR-1831
改进和新功能
更改了
.erlang
加载的默认行为:不再从当前目录加载.erlang
。可以使用c:erlangrc(PathList)
从用户指定的目录搜索和加载.erlang
文件。escript
,erlc
,dialyzer
和typer
不再加载任何.erlang
文件。*潜在不兼容性*
自有 ID:OTP-14439
运行时系统已删除对“元组调用”的支持。元组调用是一个未记录且不受支持的功能,它允许 apply 操作的模块参数是一个元组:
Var = dict:new(), Var:size()
。此“功能”经常引起混淆,尤其是在此类调用失败时。堆栈跟踪会指出源代码中不存在的函数。对于需要因某种原因使用参数化模块或元组调用的旧代码,有一个新的编译器选项称为
tuple_calls
。当给定此选项时,编译器将为模块是变量的调用生成额外的代码,以模拟旧的行为。*潜在不兼容性*
自有 ID:OTP-14497
在诸如
example({ok, Val}) -> {ok, Val}.
的代码中,将构建一个元组。编译器现在将自动将代码重写为example({ok,Val}=Tuple) -> Tuple.
,这将减少代码大小,执行时间并消除 GC 压力。自有 ID:OTP-14505
改进了只能成功执行一个 case 分支的
case
表达式的优化。自有 ID:OTP-14525
对二进制匹配的某些使用进行了轻微改进,消除了不必要的寄存器改组。
自有 ID:OTP-14594 辅助 ID:ERL-444
编译器有一个新的
{compile_info,Info}
选项,允许基于 BEAM 的语言(如 Elixir 和 LFE)添加自己的编译器版本。自有 ID:OTP-14615 辅助 ID:PR-1558
由于指令操作数的更好打包,64 位系统中加载的 BEAM 代码需要更少的内存。
这些内存节省是通过对构建运行时系统和 BEAM 编译器时使用的
beam_makeops
脚本进行重大改进而实现的。此外,beam_makeops
还有新的文档,描述了如何实现新的 BEAM 指令和加载器转换。该文档在源代码目录或 git 存储库的此处:erts/emulator/internal_doc/beam_makeops.md。在线版本可以在这里找到:https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/beam_makeops.md自有 ID:OTP-14626
二进制构造的大小计算得到了一定的优化,从而产生了较小的代码。
自有 ID:OTP-14654
当忽略从 '
catch
' 表达式返回的值时,如果捕获到异常,则不会构建堆栈跟踪。这将节省时间并减少垃圾产生。编译器和运行时系统也对 'try
/catch
' 进行了一些小的优化。自有 ID:OTP-14683
'
try/catch
' 中有一个新的语法,用于检索堆栈跟踪,而无需调用 'erlang:get_stacktrace/0
'。有关新语法的描述,请参阅参考手册。 'erlang:get_stacktrace/0
' BIF 现在已弃用。自有 ID:OTP-14692
以下是编译器的内部更改,编译器正常使用时不会注意到:模块
v3_life
已被删除。其功能已简化并集成到v3_codegen
中。自有 ID:OTP-14712
二进制匹配的优化会延迟子二进制文件的创建(请参阅《效率指南》),这可能会因参数顺序而受阻,并且可能需要更改参数顺序。现在,编译器变得更智能,可以处理任何参数顺序。
自有 ID:OTP-14774
当编译器面对复杂的 case 表达式时,它会不必要地分配堆栈元素并在 x 和 y 寄存器之间改组数据。改进了代码生成,仅在绝对必要时才分配堆栈帧。
自有 ID:OTP-14808 辅助 ID:ERL-514
编译器和 '
erlc
' 有一个新的选项 'makedep_side_effect
',用于生成依赖项并继续像正常一样编译。自有 ID:OTP-14830
当编译具有巨大函数的模块时,编译器会为其内部生成大量原子,有时会生成太多以至于原子表会溢出。编译器已被重写为生成更少的内部原子,以避免填充原子表。
自有 ID:OTP-14968 辅助 ID:ERL-563
模块、名称和元数具有字面值的外部函数(例如,
erlang:abs/1
)现在被视为字面值。这意味着更有效的代码,可以在堆上产生更少的垃圾。自有 ID:OTP-15003
添加了两个新的在映射上操作的保护 BIF:
map_get/2
和is_map_key/2
。它们与maps:get/2
和maps:is_key/2
的功能相同,只是允许在保护语句中使用它们。自有 ID:OTP-15037 辅助 ID:PR-1784, PR-1802
字面外部函数的调用或应用将替换为直接调用。
自有 ID:OTP-15044 辅助 ID:ERL-614
已实现 EEP-44 的一部分。
有一个新的预定义宏称为
OTP_RELEASE
,它是一个整数,指示 OTP 发布版本号(在此版本中,其值为21
)。有新的预处理器指令
-if(Condition).
和-elif(Condition).
。if/elif
支持内置函数defined(Symbol)
。自有 ID:OTP-15087 辅助 ID:PR-1810
编译器 7.1.5.2
已修复的错误和故障
修复了 OTP-15204 中的一个回归,该回归删除了某些外部构建工具所依赖的
.beam
文件元数据。自有 ID: OTP-15292
编译器 7.1.5.1
已修复的错误和故障
修复了使用
+deterministic
选项编译的文件如果它们在不同的目录中编译但其他方面相同则不同的问题。自有 ID: OTP-15204 辅助 ID: ERL-679
编译器 7.1.5
已修复的错误和故障
内部编译器传递 (
beam_validator
) 用于验证生成的代码已得到加强。从 BEAM 汇编代码进行编译时,
beam_type
优化器传递可能会使代码不安全。已更正。自有 ID:OTP-14863
更正了从二进制文件中匹配出来的整数并用于位运算的优化。
自有 ID:OTP-14898
编译器 7.1.4
已修复的错误和故障
当在源代码的
-compile()
属性中给出 'deterministic
' 选项时,该选项未被识别。自有 ID:OTP-14773 辅助 ID:ERL-498
编译器 7.1.3
已修复的错误和故障
对于某些复杂的位语法匹配,编译器可能会发出不正确的内部一致性失败诊断。
自有 ID:OTP-14640 辅助 ID:ERL-490
编译器 7.1.2
已修复的错误和故障
在优化过程中,没有考虑保护 BIF 上的失败标签,并且验证过程中的错误有时会阻止在发生故障时注意到此问题。
自有 ID:OTP-14522 辅助 ID:ERIERL-48
当从 Core Erlang 进行编译时,函数位置中带有嵌套 apply 的 'apply' 将被视为无效调用。已更正。(感谢 Mikael Pettersson 报告此错误。)
自有 ID:OTP-14526
修复了
beam_validator
模块中的二进制匹配检查,以确保在编译时发现潜在的编译器错误,而不是在运行时作为模拟器崩溃发现。自有 ID:OTP-14591
当使用多个
catch
子句时,可能会出现erlang:get_stacktrace/0
在try
块之外使用的错误警告。自有 ID:OTP-14600 辅助 ID:ERL-478
改进和新功能
Erlang 代码 linter 不再检查
nowarn_deprecated_function
选项中提到的函数是否在模块中声明。自有 ID:OTP-14378
编译器 7.1.1
已修复的错误和故障
在优化过程中,没有考虑保护 BIF 上的失败标签,并且验证过程中的错误有时会阻止在发生故障时注意到此问题。
自有 ID:OTP-14522 辅助 ID:ERIERL-48
编译器 7.1
已修复的错误和故障
在许多版本中,使用具有相同名称的本地函数覆盖 BIF 是合法的。但是,不允许在列表推导式中调用与保护 BIF 同名的本地函数作为过滤器。
自有 ID:OTP-13690
当给定选项 '
from_core
'、'from_asm
' 或 'from_beam
' 之一时,compile:forms/2 不会按文档返回模块名称。此外,如果将这些选项之一与 'native
' 结合使用,编译器将崩溃。自有 ID:OTP-14408 辅助 ID:ERL-417
改进和新功能
优化了以原子为第一个元素的元组的测试。
自有 ID:OTP-12148
现在,编译具有巨大字面二进制字符串的模块的速度要快得多。
自有 ID:OTP-13794
替换了已弃用的符号
时间单位
表示形式的用法。自有 ID:OTP-13831 辅助 ID:OTP-13735
已移除未公开且不受支持的模块
sys_pre_expand
。作为该功能的部分替代,现在有一个新函数erl_internal:add_predefined_functions/1
,并且erl_expand_records
现在会向 BIF 和导入函数的调用添加模块前缀。内部 ID: OTP-13856
内部编译器传递现在会以“@”开头所有生成的变量,以避免与 Elixir 或 LFE 等语言的变量发生任何冲突。
内部 ID: OTP-13924
函数
fmod/2
已添加到math
模块。内部 ID: OTP-14000
改进了复杂 guard 的代码生成。
内部 ID: OTP-14042
编译器现在会针对重复的相同 map 键发出新警告。
例如,一个 map 表达式:
#{'a' => 1, 'b' => 2, 'a' => 3}。
将会为重复的键 'a' 生成警告。
内部 ID: OTP-14058
默认情况下,现在使用
export_all
时会发出警告。可以使用nowarn_export_all
禁用此警告。内部 ID: OTP-14071
通过首先只检查每个子句中的公共键,而不是所有键,优化 map 模式匹配。这将减少 map 模式匹配中每个键的查找次数。
内部 ID: OTP-14072
有一个新的 '
deterministic
' 选项,用于省略 BEAM 文件中的 'source
' 和 'options
' 元组。内部 ID: OTP-14087
现在分析具有巨大字符串的二进制构造的模块快得多。编译器编译此类模块的速度也稍微快一些。
内部 ID: OTP-14125 辅助 ID: ERL-308
原子现在可以包含任意 Unicode 字符。
内部 ID: OTP-14178
compile:file/2
现在接受extra_chunks
选项,以便在 BEAM 文件中包含额外的块。内部 ID: OTP-14221
存储在 BEAM 文件中的调试信息格式(当使用
debug_info
时)已更改。此更改的目的是为了更好地支持其他基于 BEAM 的语言,例如 Elixir 或 LFE。OTP 中包含的所有工具(dialyzer、debugger、cover 等)都将处理新格式和之前的格式。使用
beam_lib:chunk(Beam, [abstract_code])
检索调试信息的工具将继续使用新格式和旧格式。调用beam_lib:chunk(Beam, ["Abst"])
的工具将无法使用新格式。有关更多信息,请参见
beam_lib
文档中对debug_info
的描述,以及compile
文档中对{debug_info,{Backend,Data}}
选项的描述。内部 ID: OTP-14369 辅助 ID: PR-1367
在将来的版本中,
erlang:get_stacktrace/0
可能仅在从 'try
' 表达式内部调用时才起作用(否则它将返回[]
)。为了帮助为该更改做好准备,如果 '
get_stacktrace/0
' 的使用方式在将来不起作用,编译器现在默认会发出警告。请注意,如果 'get_stacktrace/0
' 在既不使用 'catch
' 也不使用 'try
' 的函数中使用,则不会发出警告(因为如果该函数是从 'try
' 内部调用的,则这可能是合法的用法)。内部 ID: OTP-14401
编译器 7.0.4.1
修复的错误和故障
在优化过程中,没有考虑保护 BIF 上的失败标签,并且验证过程中的错误有时会阻止在发生故障时注意到此问题。
自有 ID:OTP-14522 辅助 ID:ERIERL-48
编译器 7.0.4
修复的错误和故障
次要的内部更改。文档中的一个拼写错误也已修复。
内部 ID: OTP-14240
编译器 7.0.3
修复的错误和故障
修复了匹配 map 时编译器崩溃的问题。
内部 ID: OTP-13931 辅助 ID: ERL-266
修复了与延迟子创建优化相关的编译器崩溃。(感谢 Jose Valim 报告此错误。)
内部 ID: OTP-13947 辅助 ID: ERL-268
编译器选项
inline_list_funcs
意外地关闭了一些其他优化。内部 ID: OTP-13985
当启用内联时,编译器有时会生成虚假的警告。
内部 ID: OTP-14040 辅助 ID: ERL-301
编译器 7.0.2
修复的错误和故障
如果编译器无法写入 BEAM 文件,它现在将报告写入操作的错误原因。
内部 ID: OTP-13701
修复了一个内部编译器错误。(感谢 Svilen Ivanov 报告此错误。)
内部 ID: OTP-13780 辅助 ID: ERL-202
当尝试编译具有多个 catch 的复杂表达式时,编译器可能会崩溃,所有这些都在一行上。(感谢 Thomas Arts 报告此错误。)
内部 ID: OTP-13804 辅助 ID: ERL-209
消除了一些内部编译器故障。
内部 ID: OTP-13863
编译器 7.0.1
修复的错误和故障
在 19.0 中引入了字面二进制匹配回归,其中匹配可能无法解析为正确的子句。现在已修复此问题。
内部 ID: OTP-13738
编译器 7.0
修复的错误和故障
当在已被另一个进程删除的工作目录中使用时,
compile:forms/1,2
将会崩溃。内部 ID: OTP-13430 辅助 ID: ERL-113
当被分析的模块中存在无效的函数调用(例如
42(7)
)时,Dialyzer 不再崩溃。编译器现在会警告无效的函数调用,例如X = 42, x(7)
。内部 ID: OTP-13552 辅助 ID: ERL-138
改进和新功能
元组匹配的优化已略有改进。
内部 ID: OTP-12951
已删除
core_lib
模块中五个已弃用且未公开的函数。这些函数是:get_anno/{1,2}
、is_literal/1
、is_literal_list/1
和literal_value
。请改用cerl
模块中的相应函数。内部 ID: OTP-12979
预处理器现在可以展开 ?FUNCTION_NAME 和 ?FUNCTION_ARITY 宏。
内部 ID: OTP-13059
函数 mapfold/4 已添加到
cerl_trees
模块。内部 ID: OTP-13280
位串推导已泛化为允许在构造部分中使用任意表达式。
内部 ID: OTP-13289
编译器现在会针对永远不会匹配的二进制模式发出警告(例如:
<<-1/unsigned>> = Bin
)。内部 ID: OTP-13374 辅助 ID: ERL-44
编译器将不再将编译日期和时间放入 BEAM 文件。这意味着在同一台计算机上使用相同的源代码和编译选项编译的两个 BEAM 文件将是相同的。
注意:如果要查找磁盘上的 BEAM 文件是否与加载的代码不同,请将从
Mod:module_info(md5)
获取的 MD5 值与从beam_lib:md5(BeamFileForMod)
获取的 MD5 值进行比较.
*潜在不兼容性*
内部 ID: OTP-13504
已添加函数
compile:env_compiler_options/0
,以允许工具获取与编译器本身相同的默认编译器选项。内部 ID: OTP-13654
编译器 6.0.3.1
修复的错误和故障
在优化过程中,没有考虑保护 BIF 上的失败标签,并且验证过程中的错误有时会阻止在发生故障时注意到此问题。
自有 ID:OTP-14522 辅助 ID:ERIERL-48
编译器 6.0.3
修复的错误和故障
函数调用中复杂的 guard 表达式可能会导致编译器崩溃。(感谢 Thomas Arts 报告此错误。)
内部 ID: OTP-13208
在 catch 中的 guard 中构造 map 可能会导致编译器崩溃。(感谢 Thomas Arts 报告此错误。)
内部 ID: OTP-13223
将 fun 更新为好像它是一个 map 会导致编译器崩溃。(感谢 Thomas Arts 报告此错误。)
内部 ID: OTP-13231
修复了 Core Maps 的美化打印
当美化打印结果时,字面量 map 可能会导致 Dialyzer 崩溃。
内部 ID: OTP-13238
在编译期间,位语法匹配操作的复杂组合将导致内部一致性检查失败。(感谢 Jose Valim 报告此错误。)
内部 ID: OTP-13309
编译器 6.0.2
修复的错误和故障
修复了 cerl_trees:label/2 的 map K/V 交换错误
内部 ID: OTP-13091
当给定 '
bin_opt_info
' 选项时产生的警告有时会缺少文件名和行号。(感谢 José Valim 报告此错误。)内部 ID: OTP-13113
编译器 6.0.1
修复的错误和故障
修复
get_map_elements
寄存器损坏问题当采用失败标签时,指令
get_map_elements
可能会破坏目标寄存器。仅在具有两个,且只有两个目标寄存器的模式中观察到。特别是如果我们复制一个寄存器然后跳转时。内部 ID:OTP-12967
编译器 6.0
已修复的错误和故障
编译器会优化掉那些实际上从未使用过的术语的构建。因此,OTP 18 中的编译器可能会比 OTP 17 中的编译器为构建但未使用的术语产生更多警告。
内部 ID:OTP-12453
使用 map 可能会错误地抑制未使用的变量的警告。
内部 ID:OTP-12515
编译器现在可以正确报告未知的解析转换。也就是说,来自解析转换本身的
undef
异常与解析转换的缺失报告不同。内部 ID:OTP-12723
如果 map 指令在一个子句中,则允许“延迟创建子二进制文件”优化。
内部 ID:OTP-12758
改进和新特性
现在已记录编译器应用程序中的
cerl
和cerl_trees
模块。内部 ID:OTP-11978
已删除不推荐使用的 '
asm
' 选项。*潜在不兼容性*
内部 ID:OTP-12100
支持在表达式和模式中使用变量作为 Map 键
Erlang 将接受任何表达式作为 Map 表达式中的键,并且它将接受字面量或已绑定的变量作为 Map 模式中的键。
内部 ID:OTP-12218
在 beam_type 编译器优化过程中推断 Map 类型信息。
内部 ID:OTP-12253
编译器优化已得到改进。
内部 ID:OTP-12393
模块
core_lib
中的五个未记录的函数已被弃用,并将在下一个主要版本中删除。这些函数是:get_anno/{1,2}
、is_literal/1
、is_literal_list/1
和literal_value
。请改用cerl
模块中的相应函数。内部 ID:OTP-12497
将一些内部数据结构更改为 Map,以加快编译时间。测得的加速约为 10%-15%。
内部 ID:OTP-12774
修复 Map 指令 get_map_elements 的 beam_bool 传递
在 beam_split 之前,get_map_elements 指令仍然在块中,而 beam_jump 中的辅助函数没有反映这一点。
内部 ID:OTP-12844 辅助 ID:17
编译器 5.0.4
已修复的错误和故障
从记录中匹配出一个 map,然后更新该记录可能会在运行时导致“badarg”异常。(感谢 Dmitry Aleksandrov 报告此错误。)
内部 ID:OTP-12402
当编译一些复杂的、无意义的 guard(例如)时,编译器会崩溃
...
when {{X}}, -X
...内部 ID:OTP-12410
在极少数情况下,在 map 模式的值部分使用二进制模式会导致编译器崩溃。
内部 ID:OTP-12414
将 map 包装在元组或列表中的 case 表达式,例如
case {a,Map} of
{a,#{k:=_}}=Tuple -> Tuple
end.
会被不安全地“优化”,要么导致运行时异常,要么返回一个空 map。
内部 ID:OTP-12451
当使用 '
==
' 运算符将变量与字面 map 进行比较时,编译器会将运算符更改为 '=:=
',因为它更高效。但是,如果 map 字面量具有数字键或值,则此优化是不安全的。现在,编译器只有在所有键和值都为非数字时才会进行优化。内部 ID:OTP-12456
编译器 5.0.3
已修复的错误和故障
具有相同名称和 arity 的命名 fun 可能会相互混淆。
内部 ID:OTP-12262
在 dialyzer 模式下合并 map 键
这修复了提交 805f9c89fc01220bc1bb0f27e1b68fd4eca688ba 中引入的回归问题。该问题发生在启用 dialyzer 选项“+dialyzer”编译的复合 map 键上。
报告者:Ivan Uemlianin
内部 ID:OTP-12347
编译器 5.0.2
已修复的错误和故障
更正了启用内联时代码生成不正确的错误。
内部 ID:OTP-12132
编译器 5.0.1
已修复的错误和故障
现在已修复一个涉及 Map 类型分析的 Dialyzer 崩溃问题。
内部 ID:OTP-11947
如果
-ifdef
或-indef
的 false 分支中包含拉丁字符 1,则编译器将无法编译文件。内部 ID:OTP-11987
编译器 5.0
已修复的错误和故障
当诸如 '
<<Bin/binary,...>>
' 之类的二进制构造失败时,行号将不正确。(感谢 Stanislav Seletskiy 报告此错误。)内部 ID:OTP-11572
编译器现在可以正确注释 '
try
' 的 'after
' 子句中 value 中的代码,以便 Dialyzer 不再为不匹配的返回生成虚假警告。内部 ID:OTP-11580
一些没有子句匹配的 case 语句可能会导致编译器内部错误。(感谢 Erik Soe Sorensen 报告此错误。)
内部 ID:OTP-11610
使用
--Wunmatched_returns
,当列表推导式的值被忽略时,dialyzer 将不再发出警告,前提是列表中的每个值都将是原子值(例如整数或原子,而不是元组和列表)。示例:忽略 '[io:format(...) || ...]
' 不会引发警告,而忽略 '[file:close(Fd) || ...]
' 则会。内部 ID:OTP-11626
匹配出一个二进制文件并将该二进制文件像一个 fun 一样应用,会导致运行时系统崩溃。(感谢 Loïc Hoguin。)
内部 ID:OTP-11672
一些从列表中删除最后一个元素的本地实现被
lists:droplast/1
替换。请注意,这至少需要stdlib-2.0
,它是 OTP 17.0 中交付的 stdlib 版本。(感谢 Hans Svensson)内部 ID:OTP-11678
允许一次性禁止所有自动导入。引入 no_auto_import 属性:-compile(no_auto_import)。对于总是使用限定函数名称并希望避免自动导入的函数与本地函数冲突的代码生成工具非常有用。(感谢 José Valim。)
内部 ID:OTP-11682
以下应用程序的应用程序升级 (appup) 文件已更正
asn1、common_test、compiler、crypto、debugger、dialyzer、edoc、eldap、erl_docgen、et、eunit、gs、hipe、inets、observer、odbc、os_mon、otp_mibs、parsetools、percept、public_key、reltool、runtime_tools、ssh、syntax_tools、test_server、tools、typer、webtool、wx、xmerl
一个新的用于测试 appup 文件的测试实用程序已添加到 test_server。现在 OTP 中的大多数应用程序都使用它。
(感谢 Tobias Schlager)
内部 ID:OTP-11744
使 'asm' 弃用消息适应新的版本方案。(感谢 Tuncer Ayaz)
内部 ID:OTP-11751
Ulf Norell 报告了许多编译器错误,其中不寻常或无意义的代码会导致编译器崩溃,Anthony Ramine 对这些错误进行了更正。
内部 ID:OTP-11770
改进和新特性
使用点运算符进行大量记录访问的模块的编译时间已得到改进。
内部 ID:OTP-10652
编译器可以通过将 let 表达式移动到序列中来生成更好的代码。(感谢 Anthony Ramine。)
内部 ID:OTP-11056
禁止在二进制生成器的模式中使用未调整大小的字段,并简化 v3_core 对位字符串生成器的转换。(感谢 Anthony Ramine。)
内部 ID:OTP-11186
现在可以给 Fun 命名。感谢 Richard O'Keefe 的想法 (EEP37) 以及 Anthony Ramine 的实现。
内部 ID:OTP-11537
使用
from_asm
选项从 BEAM 汇编代码生成 BEAM 文件通常会失败,因为早期的优化传递无法理解后续优化传递会引入的指令。(感谢 Anthony Ramine。)内部 ID:OTP-11544
.core
和.S
扩展名现在已记录在erlc
文档中,并且 'from_core
' 和 'from_asm
' 选项现在已记录在编译器文档中。(感谢 Tuncer Ayaz。)内部 ID:OTP-11547
构建元组或列表的 case 表达式的优化已得到改进。
内部 ID:OTP-11584
EEP43:新数据类型 - Map
使用 Map,您可以例如
____ -
M0 = #{ a => 1, b => 2}, % 创建关联
____ -
M1 = M0#{ a := 10 }, % 更新值
____ -
M2 = M1#{ "hi" => "hello"}, % 添加新关联
____ -
#{ "hi" := V1, a := V2, b := V3} = M2. % 将键与值匹配
有关如何使用 Map 的信息,请参阅参考手册中的 Map 表达式部分。
当前实现不包含以下特性:
____ - 不支持变量键
____ - 不支持单值访问
____ - 不支持 map 推导式
请注意,在 OTP 17.0 期间,Maps 处于实验性阶段。
自有 ID:OTP-11616
为了允许使用 edoc,一些函数规范被修正或移动,并且一些 edoc 注释被修正。(感谢 Pierre Fenoll)
自有 ID:OTP-11702
感谢 Anthony Ramine 为 BEAM 编译器中的优化所做的多项改进,以及清理将列表和二进制推导式转换为 Core Erlang 的代码。
自有 ID:OTP-11720
Erlang 源文件的默认编码现在是 UTF-8。 作为一项临时措施,以缓解从旧的 latin-1 默认编码过渡,如果编译器遇到无效的 UTF-8 序列的字节序列,编译器将以 latin-1 模式重试编译。此解决方法将在未来的版本中删除。
自有 ID:OTP-11791
编译器 4.9.4
已修复的错误和故障
拼写错误修复:ambigous -> ambiguous。 感谢 Leo Correa。
自有 ID:OTP-11455
改进和新功能
将 “after” 代码块提升为零元函数。感谢 Anthony Ramine。
自有 ID:OTP-11267
编译器 4.9.3
已修复的错误和故障
诸如
'B = is_integer(V), if B and B -> ok end'
之类的表达式会导致编译器崩溃。自有 ID:OTP-11240
compile:file2/2
使用选项report_errors
时可能会返回只有两个元素的 ErrorInfo 元组,而文档说明 ErrorInfo 元组始终具有三个元素。 还更新了文档,添加了如果行号不适用,则第一个元素可能为“none
”。自有 ID:OTP-11304 辅助 ID:seq12412
改进和新功能
修复了中间字节序机器浮点数的匹配。 感谢 Johannes Weissl。
自有 ID:OTP-11201
限制了本地函数引用的内联。感谢 Anthony Ramine。
自有 ID:OTP-11211
消除了一些推导式产生的误导性警告。感谢 Anthony Ramine。
自有 ID:OTP-11212
禁止在 beam_validator 中返回匹配上下文。感谢 Anthony Ramine。
自有 ID:OTP-11247
编译器 4.9.2
已修复的错误和故障
在保护语句中使用复杂的布尔运算编译函数可能非常缓慢。(感谢 Magnus Muller 报告此问题。)
自有 ID:OTP-10939
在 receive 语句中使用的某些保护表达式可能会导致编译器崩溃。
自有 ID:OTP-11119 辅助 ID:seq12342
改进和新功能
修复了一些二进制推导式的优化。感谢 Anthony Ramine。
自有 ID:OTP-11005
在 beam_receive 中使用集合来存储 ref 寄存器。感谢 Anthony Ramine。
自有 ID:OTP-11069
修复 bs_put_string 指令的重命名。感谢 Anthony Ramine。
自有 ID:OTP-11129
编译器 4.9.1
已修复的错误和故障
编译器会尝试编译诸如 “element(2, not_tuple)” 之类的表达式时崩溃。
自有 ID:OTP-10794
禁止在 Core Erlang 序列参数中使用多个值。感谢 José Valim 和 Anthony Ramine。
自有 ID:OTP-10818
不安全的优化会导致编译器对某些复杂的代码序列崩溃并出现内部错误。
自有 ID:OTP-10825 辅助 ID:seq12247
改进和新功能
将在表达式中产生浮点结果的整数(例如“
X / 2
”)现在将在编译时转换为浮点数。(由 Richard O'Keefe 建议。)模块中相同的浮点常量现在将合并到常量池中的一个条目中。
自有 ID:OTP-10788
编译器 4.9
改进和新功能
编译器优化已经过改进,在某些情况下,代码质量会略好一些。
自有 ID:OTP-10193
已实现对 Unicode 的支持。
自有 ID:OTP-10302
必要时,已在 Erlang 文件中添加了声明编码的注释。当 UTF-8 成为默认编码时,此注释将在 Erlang/OTP R17B 中删除。
自有 ID:OTP-10630
修复了由选项 inline_list_funcs 触发的一些错误警告。感谢 Anthony Ramine。
自有 ID:OTP-10690
禁止在 Core Erlang 保护语句中使用本地函数变量。感谢 Anthony Ramine。
自有 ID:OTP-10706
二进制语法匹配可能会导致编译器出现内部一致性错误。(感谢 Viktor Sovietov 报告此错误。)
自有 ID:OTP-10724
编译器 4.8.2
已修复的错误和故障
具有大量函数的模块编译速度会非常慢。
自有 ID:OTP-10123
compile:forms/2
现在将使用 {source,SourceFilePath} 设置module_info(compile)
返回的源(感谢 José Valim)自有 ID:OTP-10150
启用了 trap_exit 的进程在调用编译器后会收到 EXIT 消息。(感谢 Jeremy Heater。)
自有 ID:OTP-10171
修复了带列号的消息排序
自有 ID:OTP-10183
sys_pre_expand: 修复 BASE 永远不会被设置的问题
提交 a612e99fb5aaa934fe5a8591db0f083d7fa0b20a 将模块属性从 2 元组更改为 3 元组,但忘记更新 get_base/1,从而破坏了参数化模块的 BASE。
自有 ID:OTP-10184
如果使用了文字元组函数,编译器现在会发出警告。 例如,{erlang,is_tuple}(X) 现在会生成警告。
自有 ID:OTP-10185
编译器现在会警告二进制构造中段的非法大小。 例如,<<X:(2.5)>> 现在会导致编译器发出警告。
自有 ID:OTP-10197
修复 erlc -MP 标志
由于 erlc.c 中的一个复制粘贴错误,-MP 标志与 -MG 具有相同的效果。 作为一种解决方法,您必须传递 +makedep_phony 才能启用 MP 选项。 此补丁使 -MP 按预期工作。
自有 ID:OTP-10211
编译器 4.8.1
已修复的错误和故障
在极少数情况下,编译器在编译 case 语句时可能会崩溃。(感谢 Hakan Mattsson。)
自有 ID:OTP-9842
如果在保护语句的顶层调用保护测试(例如 is_list/1),如果存在同名的本地定义,则会导致编译器崩溃。 已更正为拒绝该程序并显示错误消息。
自有 ID:OTP-9866
在
try
代码块中使用get/1
在某些情况下会导致内部编译器错误。(感谢 Eric Merritt。)自有 ID:OTP-9867
如果使用
inline
选项编译模块,则未导出的 on_load 函数将不会运行。(感谢 Yiannis Tsiouris。)自有 ID:OTP-9910
修复了 compile_info 中的差异
BEAM 反汇编器使用原子“none”来表示 .beam 文件中缺少 compile_info 块。 这与 #beam_file{} 记录的 compile_info 字段的类型声明为包含列表相冲突。 现在,[] 表示缺少此块。 这简化了代码并避免了 dialyzer 警告。
自有 ID:OTP-9917
修复“compile”文档中的拼写错误:未匹配的括号(感谢 Ricardo Catalinas Jiménez)
自有 ID:OTP-9919
在总是返回
false
的try
...catch
语句中,编译器会删除对不会导致异常的 BIF 的调用(例如put/2
)。 此类代码的示例:try put(K, V), false catch _:_ -> false end.
自有 ID:OTP-9982
编译器 4.8
已修复的错误和故障
在 stdlib 的行为中添加了 '-callback' 属性
将 stdlib 的行为中的 behaviour_info(callbacks) 导出替换为所有回调的 -callback' 属性。 使用有关回调属性的信息更新文档 从 '-callback' 属性自动生成 'behaviour_info' 函数
“behaviour_info(callbacks)” 是一个特殊的函数,它定义在描述行为的模块中,并返回其回调列表。
这个函数现在使用“-callback”规范自动生成。如果用户同时定义了“-callback”属性和 behaviour_info/1 函数,则 lint 会返回错误。如果回调不需要类型信息,则为其使用通用规范。将“-callback”属性添加到语言语法中。
行为可以使用熟悉的 spec 语法为它们的回调定义规范,将“-spec”关键字替换为“-callback”。会执行简单的 lint 检查,以确保没有回调被定义两次,并且所有引用的类型都已声明。
然后,工具可以使用这些属性来为行为提供文档,或查找回调模块中回调定义中的差异。
将回调规范添加到 kernel 中的 'application' 模块。按照互联网文档,将回调规范添加到 tftp 模块。按照可能已弃用的注释,将回调规范添加到 inets_service 模块。
自有 ID: OTP-9621
fun 的 “uniq” 值的计算(参见
erlang:fun_info/1
)过于薄弱,现已加强。它过去仅基于 fun 主体的代码,但现在基于模块的 BEAM 代码的 MD5。自有 ID: OTP-9667
改进和新功能
现在允许在 '
fun M:F/A
' 中使用变量,正如 Richard O'Keefe 在 EEP-23 中建议的那样。抽象格式中 '
fun M:F/A
' 的表示方式已进行了不兼容的更改。直接读取或操作抽象格式的工具(例如解析转换)可能需要更新。编译器可以处理新旧格式(即,从 pre-R15 BEAM 文件中提取抽象格式并使用 compile:forms/1,2 编译它将有效)。syntax_tools
应用程序也可以处理两种格式。*潜在不兼容性*
自有 ID: OTP-9643
filename:find_src/1,2
现在可以在精简的 BEAM 文件上工作(由 Per Hedeland 报告)。HiPE 编译器也可以在精简的 BEAM 文件上工作。BEAM 编译器将不再在M:module_info(compile)
中包含源代码本身给出的编译选项(因为如果重新编译模块,这些选项无论如何都会被应用)。自有 ID: OTP-9752
内联二进制匹配可能会导致内部编译器错误。(感谢 Rene Kijewski 报告此错误。)
自有 ID: OTP-9770
编译器 4.7.5
修复的错误和故障
使用
-compile()
属性在源代码中给出的编译器选项过去会在Mod:module_info(compile)
中包含两次。现在它们仅在选项列表的开头包含一次。自有 ID: OTP-9534
beam_disasm:处理精简的 BEAM 文件
如果要求 beam_disasm:file/1 反汇编没有 "Attr" 块的精简 BEAM 文件,则会崩溃。(感谢 Haitao Li)
自有 ID: OTP-9571
编译器 4.7.4
修复的错误和故障
如果在二进制匹配中匹配出一个变量并将其用作二进制元素的大小,则如果在后续匹配操作中使用,它似乎是未绑定的。(感谢 Bernard Duggan。)
自有 ID: OTP-9134
消除
sys_core_fold
中的不正确警告自有 ID: OTP-9152
编译器 4.7.3
修复的错误和故障
-export_type()
指令不再包含在属性中。自有 ID: OTP-8998
改进和新功能
Erlang 函数允许的最大参数数量已从 256 减少到 255,因此现在参数数量可以容纳在一个字节中。
自有 ID: OTP-9049
已将用于 Makefiles 的依赖关系生成添加到编译器和 erlc。请参阅
compile
和erlc
的手册页。(感谢 Jean-Sebastien Pedron。)自有 ID: OTP-9065
编译器 4.7.2
修复的错误和故障
已修复 Christopher Williams 报告的两个编译器错误(会导致编译器终止)。
自有 ID: OTP-8949
改进和新功能
编译器会以混淆 Dialyzer 的方式转换包含尾部段的二进制推导式。例如
[42 || <<_:8/integer, _/bits>> <= Bits]
会产生 Dialyzer 警告。
自有 ID: OTP-8864
诸如
foo(A) -> <<A:0>>
之类的代码会导致编译器崩溃。自有 ID: OTP-8865
当变量从 receive 块导出但未使用 receive 块的返回值时,编译器可能会出现内部错误。(感谢 Jim Engquist 报告此错误。)
自有 ID: OTP-8888
编译器 4.7.1
改进和新功能
消除了自动导入 BIF 冲突的警告。
自有 ID: OTP-8840
编译器 4.7
修复的错误和故障
修复了内联器中的几个问题。
自有 ID: OTP-8552
改进和新功能
实现了来自 EEP31(和 EEP9)的模块二进制文件。
自有 ID: OTP-8217
当名称冲突时,本地和导入函数现在会覆盖自动导入的 BIF。R14 之前的行为是自动导入的 BIF 会覆盖本地函数。为避免旧程序更改行为,以下操作将产生错误
- 在没有显式模块名称的情况下调用与在 OTP R14A 之前存在(并自动导入)的自动导入的 BIF 的名称冲突的本地函数
- 显式导入与在 OTP R14A 之前存在(并自动导入)的自动导入的 BIF 的名称冲突的函数
- 使用任何形式的旧编译器指令
nowarn_bif_clash
如果 BIF 在 OTP R14A 或更高版本中添加或自动导入,则使用导入或本地函数覆盖它只会导致警告。
要解决冲突,您可以显式使用模块名称
erlang
来调用 BIF,或者使用新的编译器指令-compile({no_auto_import,[F/A]}).
删除该特定 BIF 的自动导入,这使得所有调用本地或导入函数(没有显式模块名称)的操作不会出现警告或错误。此更改使得将来添加自动导入的 BIF 不会破坏或静默更改旧代码。但是,某些巧妙利用旧行为或
nowarn_bif_clash
编译器指令的当前代码可能需要更改才能被编译器接受。*潜在不兼容性*
自有 ID: OTP-8579
已删除未记录、不支持和已弃用的函数
lists:flat_length/1
。自有 ID: OTP-8584
现在可以在没有括号的情况下访问嵌套记录。有关示例,请参阅参考手册。(感谢 YAMASHINA Hio 和 Tuncer Ayaz。)
自有 ID: OTP-8597
现在可以通过将忽略的值 "_" 分配给它来抑制诸如 “
list_to_integer(S), ok
” 之类代码中的警告,如下所示:“`_ = list_to_integer(S), ok`”。自有 ID: OTP-8602
现在对只能读出一个新创建的引用的
receive
语句进行了特殊优化,以便它将以恒定时间执行,而与进程的接收队列中的消息数量无关。此优化将使对gen_server:call()
的调用受益。(有关将优化的 receive 语句的示例,请参阅gen:do_call/4
。)自有 ID: OTP-8623
编译器更好地优化了记录操作。
自有 ID: OTP-8668
编译器 4.6.5
修复的错误和故障
在 if 中使用复杂的布尔表达式可能会导致编译器崩溃或以内部错误终止。(感谢 Simon Cornish。)
自有 ID: OTP-8338
现在可以在参数化模块中使用位字符串推导式。(感谢 Jebu Ittiachen。)
自有 ID: OTP-8447
改进和新功能
on_load 函数的预期返回值已更改。(请参阅参考手册中有关代码加载的部分。)
*潜在不兼容性*
自有 ID: OTP-8339
在极少数情况下,当使用垃圾回收保护 BIF 时,验证过程 (beam_validator) 会发出代码不安全的信号,而实际上代码是正确的。(感谢 Kiran Khaladkar。)
自有 ID: OTP-8378
对于
erlc
的-Werror
选项以及编译器选项warnings_as_errors
,会将警告视为错误。(感谢 Christopher Faulet。)内部 ID:OTP-8382
已实现宏重载。(感谢 Christopher Faulet。)
内部 ID:OTP-8388
编译器 4.6.4
修复的 Bug 和故障
编译器的 'E' 选项现在可以用于带有类型和规范的模块。
内部 ID:OTP-8238 辅助 ID:OTP-8150
在列表推导式中,某些在
begin
-end
中使用二进制匹配的情况可能会导致编译器崩溃或生成不正确的代码。内部 ID:OTP-8271
改进和新功能
文档现在使用大多数平台上存在的开源工具(xsltproc 和 fop)构建。一个可见的变化是移除了框架。
内部 ID:OTP-8201
如果在列表推导式中使用了对 is_record/2 的无效调用,编译器可能会崩溃。(感谢 Tobias Lindahl。)
内部 ID:OTP-8269
可以使用 -on_load() 指令在模块加载时运行函数。它在参考手册中关于代码加载的部分进行了说明。
内部 ID:OTP-8295
编译器 4.6.3
改进和新功能
修正了活跃性优化,以消除编译位语法构造代码时可能发生的编译器崩溃。(感谢 Mikage Sawatari。)
在 try/catch 块的保护上下文中调用诸如
length/1
之类的 BIF 可能会导致编译器崩溃。(感谢 Paul Fisher。)在列表推导式中使用包含
andalso
或orelse
的过滤器表达式可能会导致编译器崩溃。(感谢 Martin Engström。)内部 ID:OTP-8054
具有嵌套 'not' 运算符的保护可能会导致编译器崩溃。(感谢 Tuncer Ayaz。)
内部 ID:OTP-8131
编译器 4.6.2
修复的 Bug 和故障
由于跳转优化器中的一个错误(仅具有向后引用的标签仍然可以被删除),编译器在编译包含
receive after
的某些复杂函数体时会崩溃。(感谢 Vincent de Phily。)内部 ID:OTP-7980
编译器 4.6.1
修复的 Bug 和故障
修复了其他一些小错误。
内部 ID:OTP-7937
改进和新功能
如果存在与空二进制匹配的子句,而没有其他与非空二进制匹配的子句,则会有更高效的代码。
内部 ID:OTP-7924
有一个新选项允许模块的模块名称与文件名不同。除非您知道自己在做什么,否则不要使用它。
内部 ID:OTP-7927
编译器 4.6.0.1
修复的 Bug 和故障
在
try
...catch
中使用andalso
/orelse
或记录访问可能会导致编译器崩溃。一些大型和复杂的函数可能需要极长的编译时间(数小时或数天)。
内部 ID:OTP-7905
编译器 4.6
修复的 Bug 和故障
对于一些使用
andalso
/orelse
的复杂保护,编译器会崩溃。(感谢 Hunter Morris。)内部 ID:OTP-7679
在位语法构造中(不正确地)使用了嵌套的
setelement/3
应用程序的值的代码可能会导致编译器崩溃。内部 ID:OTP-7690
包含巨大整数(由数十万位或更多组成)的模块编译速度可能很慢。此问题已得到纠正。
内部 ID:OTP-7707 辅助 ID:seq11129
如果列表推导式中的生成器被赋予非列表项,现在将抛出
function_clause
异常,而不是case_clause
异常(在 R12B 之前的所有版本中都是这样)。内部 ID:OTP-7844
改进和新功能
如果匹配中的二进制段的大小是复杂的文字(如二进制或元组),编译器可能会崩溃。
内部 ID:OTP-7650
编译器为匹配复杂常量(如常量列表和元组)生成更紧凑、更快的代码。
内部 ID:OTP-7655
已删除未记录、不支持和已弃用的保护 BIF
is_constant/1
。* 与 R12B 不兼容 *
内部 ID:OTP-7673
编译器为许多保护表达式生成了更好的代码,尤其是对于使用
andalso
/orelse
或记录字段的保护。(从技术上讲,保护中的
andalso
/orelse
会导致创建堆栈帧并保存所有可能在保护之后存活的 x 寄存器,并在离开保护之前恢复所有 x 寄存器。对于某些保护,保存的 x 寄存器太多,随后又被恢复。在此版本的编译器中,不会创建堆栈帧,也不会保存和恢复 x 寄存器。)内部 ID:OTP-7718
R12B 中二进制推导式创建的二进制结果的默认大小为 64Kb(如果需要,它会增长)。这通常太多了。在此版本中,默认值更改为 256 字节。此外,对于大多数没有过滤器的二进制推导式,可以预先计算出结果二进制的确切大小,编译器现在生成执行该计算的代码。
内部 ID:OTP-7737
短路运算符
andalso
和orelse
不再保证它们的第二个参数是true
或false
。因此,andalso
/orelse
现在是尾递归的。*潜在不兼容性*
内部 ID:OTP-7748
如果文件中模块名称与输出文件名不同,编译器将拒绝编译该文件。
使用
erlc
进行编译时,当前工作目录将不会包含在代码路径中(除非使用“-pa .”显式添加)。*潜在不兼容性*
内部 ID:OTP-7793
对于没有生成器的列表推导式,将不再有任何警告,因为此类列表推导式已被证明是有用的。
内部 ID:OTP-7846
现在已启用对过时的保护测试的警告。(也就是说,在保护中编写
list(L)
而不是is_list(L)
将生成警告。)可以使用
nowarn_obsolete_guard
选项关闭警告。内部 ID:OTP-7850
已更新版权声明。
内部 ID:OTP-7851
如果模块包含一个与自动导入的 BIF(例如
length/1
)同名的导出函数,则对 BIF 的任何调用都必须具有显式的erlang:
前缀,否则将出现编译错误(在之前的版本中,此类调用只会生成警告)。(更改的原因是为了避免在未来的主要版本 R14 或 R15 中破坏代码,我们计划在 R14 或 R15 中使没有模块前缀的调用始终调用同一模块中的本地函数,即使存在具有相同名称的自动导入的 BIF。)
*潜在不兼容性*
内部 ID:OTP-7873
编译器 4.5.5
修复的 Bug 和故障
在位语法中匹配零宽度段会使编译器崩溃。(感谢 Will。)
内部 ID:OTP-7591
改进和新功能
在以二进制段开头,并且至少后跟两个可变大小段的位语法表达式中,为二进制分配的空间可能太小,导致内存损坏。
内部 ID:OTP-7556
在用户定义的属性中,现在允许使用
Name/Arity
,它将被转换为{Name,Arity}
。(Richard O'Keefe 对 EEP-24 的实现。)现在,参考手册的“模块”部分中记录了自动插入到每个编译模块中的
module_info/{0,1}
函数。内部 ID:OTP-7586
编译器 4.5.4
改进和新功能
某些复杂的位语法匹配操作匹配二进制文件并且具有多个子句可能会给出不正确的结果(匹配的二进制文件太短)。(感谢 Christian von Roques 的错误报告和更正。)
内部 ID:OTP-7498
编译器 4.5.3
改进和新功能
新选项
warn_export_all
,用于警告使用export_all
的模块。(感谢 Richard Carlsson。)内部 ID:OTP-7392
编译器 4.5.2.1
修复的 Bug 和故障
在极少数情况下,length/1 BIF(以及其他一些 guard BIF)似乎会返回不正确的值(任何类型)。
自有 ID:OTP-7345 辅助 ID:seq10962
编译器 4.5.2
修复的错误和故障
修复了旧内联器中的一个错误。一些未公开的功能已被删除。
自有 ID:OTP-7223
不允许使用“=”运算符并行匹配多个二进制模式(这是一个实现限制),但编译器并非拒绝所有此类尝试(根据模式,生成的代码可能正确工作,也可能不正确)。现在,编译器会拒绝所有用“=”连接的二进制模式。
自有 ID:OTP-7227
记录操作和二进制匹配的复杂组合可能导致编译器崩溃。(感谢 Vladimir Klebansky。)
自有 ID:OTP-7233
在极少数情况下,将二进制匹配子句与其他匹配其他数据类型的子句混合使用,可能会导致编译器崩溃。
自有 ID:OTP-7240 辅助 ID:seq10916
编译器 4.5.1.1
修复的错误和故障
修复了一个编译器错误,该错误可能导致复杂的二进制匹配操作在不应该失败时失败。(感谢 Tomas Stejskal。)
自有 ID:OTP-7188
在不寻常的情况下,fun 的环境可能会绑定错误的值。
自有 ID:OTP-7202 辅助 ID:seq10887
没有生成器的长列表推导序列,使用“++”运算符连接,会导致代码扩展爆炸,从而导致编译器内存耗尽。为了解决这个问题,在“
[...||...]++Expr
”中,现在会在列表推导之前计算Expr
。此更改是向后兼容的(如果您对求值顺序有疑问,请参阅以下说明)。关于求值顺序的说明:参考手册说,子表达式在表达式本身之前以任何顺序进行求值。因此,在诸如“
LeftExpr++RightExpr
”之类的表达式中,您不应依赖于在RightExpr
之前或之后对LeftExpr
进行求值。求值顺序仅在表达式包含或依赖于具有副作用的操作(例如消息传递或 ETS 操作)时才重要。自有 ID:OTP-7206
编译器 4.5.1
修复的错误和故障
函数调用中的匹配表达式可能会导致错误的“构造了一个术语但从未使用过”警告。
自有 ID:OTP-7018 辅助 ID:seq10824
如果二进制尾部被匹配出去,然后在二进制附加操作中使用,则编译器可能会崩溃。(感谢 Oleg Avdeev。)
同样,如果二进制尾部被匹配出去,然后在整数字段中的二进制构造中(不正确地)使用,则编译器可能会崩溃。(感谢 Fredrik Svahn。)或者在浮点数字段中不正确地使用。或者在具有给定长度的二进制字段中使用。(感谢 Chih - Wei Yu。)
自有 ID:OTP-7022
在记录中匹配一个空二进制文件,然后再次使用相同的记录可能会导致编译器崩溃。(感谢 Fredrik Thulin。)
自有 ID:OTP-7029
在极少数情况下,包含浮点数和整数的常量可能会被混淆。例子
f(a) -> [1]; f(b) -> [1.0].
f(a)
和f(b)
都将返回[1]
。自有 ID:OTP-7073
一些位语法代码,例如
matching d(_,<$lt;$gt;$gt;) -> one; d(0,<$lt;D$gt;$gt;) ->two.
可能会导致编译器崩溃。(感谢 Simon Cornish。)
自有 ID:OTP-7094
在不寻常的情况下,由于不安全的优化,对 fun 的调用可能会失败。(感谢 Simon Cornish。)
自有 ID:OTP-7102
具有包含两个或多个 andalso/orelse 的 guard 的位语法匹配可能会导致编译器崩溃。(感谢 Mateusz Berezecki。)
自有 ID:OTP-7113
这仅在您生成或编写自己的 Core Erlang 代码时才是一个问题:Core Erlang 优化器代码可以将嵌套调用(例如
erlang:'$lt;'(erlang:length(L), 2)
作为 case 表达式移动到 guard 中,这将更改语义。(感谢 Robert Virding。)自有 ID:OTP-7117
改进和新功能
如果记录更新代码由多个源代码行组成,则编译器可能会为记录更新生成次优代码。
自有 ID:OTP-7101
编译器 4.5
修复的错误和故障
编译器过去允许在位语法模式中,没有大小的二进制字段可以用于结尾以外的其他位置。例如,
<<B/binary,EmptyBinary/binary>> = Bin
过去可以编译,但现在编译将失败并显示错误消息。此外,现在也不允许在二进制模式中给字面字符串指定类型或大小;例如,
<<"abc"/binary>> = Bin
将不再编译。(在以前的版本中,运行时总是会有一个badmatch
异常。)自有 ID:OTP-6885
改进和新功能
位串(位级)二进制文件和二进制推导现在是语言的一部分。请参阅参考手册。
自有 ID:OTP-6558
已记录编译器的“
compressed
”选项。自有 ID:OTP-6801
如果未使用列表推导的值,例如在“
[do_something(X) || X <- List], ok
”中,则不再构建结果列表。有关更多详细信息,请参见效率指南。如果未使用表达式的值,并且该表达式除了可能引发异常外没有其他副作用,则会生成警告。示例:“
self(),ok
”和“{error,Reason},ok
”。自有 ID:OTP-6824
在
compile
模块中添加了三个新函数:noenv_file/2
、noenv_forms/2
和noenv_output_generated/1
。自有 ID:OTP-6829
许多位语法操作,包括构造和匹配,速度更快。有关更多信息,请参见效率指南。
自有 ID:OTP-6838
字面列表、元组和二进制文件不再像以前那样在运行时构造,而是存储在每个模块的常量池中。多次使用的字面量仅存储一次。
这并不是对语言的更改,而只是对其实现细节的更改。因此,此更改的影响在效率指南中进行了描述。
示例 1:在表达式
element(BitNum-1, {1,2,4,8,16,32,64,128})
中,元组过去每次执行表达式时都会构造,如果表达式在循环中执行,则可能会在两个方面对性能不利:构建元组本身的时间以及垃圾回收花费的时间,因为堆用垃圾填充得更快。示例 2:诸如
"abc"
之类的字面字符串过去以字节字符串的形式紧凑地存储在编译后的代码中,并在运行时扩展为列表。现在,所有字符串都将以扩展为列表(例如[$a,$b,$c]
)的形式存储在常量池中。这意味着该字符串在运行时将更快地使用,但是即使不使用,它也将需要更多的空间。如果空间是一个问题,则对于不常用的长字符串(例如错误消息),您可能希望使用二进制字面量(即<<"abc"<<
)而不是字符串字面量。自有 ID:OTP-6850
递归调用现在通常比 R11B 消耗更少的堆栈。请参见效率指南。
自有 ID:OTP-6862 辅助 ID:seq10746
引入了两个新的 guard BIF 作为
size/1
的推荐替代品。(size/1
BIF 不会早于 R14B 删除。)BIF 是tuple_size/1
,用于计算元组的大小;以及byte_size/1
,用于计算二进制或位串的内容所需的字节数(如果需要,则向上舍入到最接近的字节数)。还有一个新的
bit_size/1
BIF,它返回二进制或位串包含的确切位数。自有 ID:OTP-6902
两个内部函数
erl_bifs:is_bif/3
和erl_bifs:is_guard/3
已被删除。它们是不受支持、未记录且未维护的。自有 ID:OTP-6966
编译器 4.4.5
修复的错误和故障
如果您尝试将两个非列表字面量与“
++
”组合(例如,an_atom++"string"
),则编译器会崩溃。自有 ID:OTP-6630 辅助 ID:seq10635
改进和新功能
对 Makefile 进行了较小的更改。
自有 ID:OTP-6689
编译器 4.4.4
修复的错误和故障
如果旧的内联器与激进的设置一起使用,则可能会为位语法匹配生成不正确的代码。
自有 ID:OTP-6461
编译器 4.4.3
修复的错误和故障
R10B 编译器可能会生成不安全的
bs_save/bs_restore
指令,从而导致内存损坏。(R11B 编译器没有该问题。)现在,erlang 模拟器将拒绝加载包含此类不安全的bs_save/bs_restore
指令的 R10B 编译模块。此外,编译器中的 beam_validator 模块也会拒绝此类指令(以防它用于验证 R10B 代码)。(感谢 Matthew Reilly。)自有 ID:OTP-6386
改进和新功能
当给定 debug_info 选项时,现在会从存储的抽象代码中删除已运行的解析转换的指令,以防止再次运行解析转换。
自有 ID:OTP-5344
在涉及布尔表达式的一些 guard 表达式的代码生成方面进行了细微的改进。
自有 ID:OTP-6347
编译器 4.4.2.1
修复的错误和故障
编译器可能会为由多个子句组成的位语法匹配生成不正确的代码。
自有 ID:OTP-6392 辅助 ID:seq10539
编译器 4.4.2
修复的错误和故障
在
try
代码块的after
部分中定义一个包含自身的函数,会导致编译器崩溃或生成不正确的代码。(感谢 Tim Rath。)包含大量函数(10000 个或更多)的模块编译时间缩短。
(对于某些位语法匹配操作,编译器可能会生成已弃用的指令。)
自有 ID:OTP-6212 辅助 ID:seq10446
修复了几个导致警告显示时没有文件名和行号的错误。
自有 ID:OTP-6260 辅助 ID:seq10461
改进和新特性
strict_record_tests
选项现在是默认选项;也就是说,如果Record
不是正确类型的记录,则使用Record#record_tag.field
语法从记录读取字段将会失败。如有必要,可以通过指定
no_strict_record_tests
选项来关闭记录测试。为了避免编辑 Makefile,可以将环境变量ERL_COMPILER_OPTIONS
设置为 "no_strict_record_tests
"。no_strict_record_tests
选项可能会在 R12B 版本中被移除。*潜在不兼容性*
自有 ID:OTP-6294
编译器 4.4.1
修复的错误和故障
如果模块包含类似于 '
fun(1=0) -> ok end
' 的代码,编译器会崩溃。(感谢 Richard Carlsson。)编译器会花费很长时间编译位语法表达式,例如 '
<<1:(50*1024*1024)>>
',并生成一个巨大的 .beam 文件。已修复。编译器编译具有多个生成器的列表推导式时速度非常慢。(感谢 Thomas Raes。)
模块属性的存储顺序与源代码中的顺序相反。(因此,
M:module_info(attributes)
也会以相反的顺序返回属性。)在
try
代码块的after
部分中定义一个函数,会导致编译器崩溃或生成不正确的代码。(感谢 Martin Bjorklund。)二进制模式和带有 andalso/orelse 的 guard 的组合可能会导致编译器崩溃。
自有 ID:OTP-6121 辅助 ID:seq10400
编译器 4.4
修复的错误和故障
当使用
-include_lib
包含.hrl
文件时,include 路径会临时更新,以包含找到.hrl
文件的目录,这将允许该.hrl
文件本身使用-include
从同一目录包含文件。(感谢 Richard Carlsson。)自有 ID:OTP-5944
改进和新特性
andalso
和orelse
运算符现在允许在 guard 中使用。这也适用于匹配规范。自有 ID:OTP-5894 辅助 ID:OTP-5149
当给定新的选项
strict_record_tests
时,编译器将生成代码,验证 guard 中R#record.field
操作的记录类型。自 R10B 以来,已经生成了验证主体中记录类型的代码,但在本版本中,如果记录验证测试失败,将会出现{badrecord,RecordTag}
而不是badmatch
。有关更多信息,请参阅compile
。Erlang shell 始终应用严格的记录测试。
自有 ID:OTP-5915 辅助 ID:OTP-5714
BIF
is_record/3
现在可以在 guard 中使用。此外,为了与其他is_*
函数保持一致性,现在可以调用is_record/3
,而无需使用erlang:
模块前缀。自有 ID:OTP-5916
编译器选项
ignore_try
和ignore_cond
已被删除,这些选项允许将未加引号的try
或cond
用作原子或记录标签。依赖这些选项的旧代码需要修改,以将try
或cond
作为原子或记录标签的情况改为单引号括起来。(注意:虽然cond
是保留关键字,但没有cond
语句。它可能会在未来的版本中引入。)*潜在不兼容性*
自有 ID:OTP-6058
编译器 4.3.12
改进和新特性
以下代码会导致编译器崩溃:
case T of #r{s = ""} -> T #r{s = "x"} end
。(感谢 Richard Carlsson。)如果在某些涉及布尔运算符(包括分号)的 guard 中构造二进制文件,编译器可能会崩溃。(感谢 Torbjorn Tornkvist。)
自有 ID:OTP-5872
编译器现在会警告
megaco:format_versions/1
函数已弃用。自有 ID:OTP-5976
编译器 4.3.11
改进和新特性
如果将带有别名 ('=') 的某些模式拆分为多行,编译器会假定它们不匹配。(感谢 Peter Nagy/Mats Cronqvist。)
对消除 Dialyzer 警告进行了小幅清理。
自有 ID:OTP-5791 辅助 ID:seq10141
编译器 4.3.10
修复的错误和故障
当给定新的选项
strict_record_tests
时,编译器将生成代码,验证R#record.field
操作的记录类型(仅在主体上下文中,不在 guard 中)。有关更多信息,请参阅compile
模块的文档。当给定某些 catch 和记录操作的组合时,编译器的 beam 验证器传递在极少数情况下可能会崩溃。(感谢 Mats Cronqvist。)
包含二进制文件的属性(例如 -a(<<1,2,3>>)) 会导致编译器崩溃。(感谢 Roger Price。)
同一模块中的多个行为将不再生成警告,除非一个或多个行为的回调重叠。例如,在同一模块中使用
application
和supervisor
行为将不会生成任何警告,但使用gen_server
和gen_fsm
则会生成警告。自有 ID:OTP-5714 辅助 ID:seq10073
预处理器过去会抱怨宏定义
-define(S(S), ??S).
是循环的,但实际上并非如此。(感谢 Richard Carlsson。)自有 ID:OTP-5777
编译器 4.3.9
修复的错误和故障
使用字面字符串更新记录的至少两个字段可能会导致编译器生成危险的代码,从而在运行时导致崩溃(例如,
R#r{a="abc",b=1}
)。(感谢 Mikael Karlsson。)不必要的测试(例如具有两个相同 case 分支的 'case')可能会导致编译器崩溃。(感谢 Fredrik Thulin。)
当在 try/catch 语句中使用浮点运算时,编译器的验证传递可能会为正确的代码生成错误。
在位语法构造中,任何跟在二进制字段之后的字段都将始终标记为“对齐”(这可能正确也可能不正确)。如果该字段实际上未对齐,则会导致 hipe 本机编译器生成不正确的代码。(感谢 Per Gustafsson。)
一些复杂的 guard 表达式(例如
A#a.b==""; A#a.b==undefined
)会导致编译器崩溃。(感谢 Sean Hinde。)对于具有许多函数和/或原子的模块(例如 Asn1 应用程序或其他代码生成器生成的模块),编译速度已提高。
自有 ID:OTP-5632 辅助 ID:seq10057
编译器 4.3.8
修复的错误和故障
在某些情况下,函数体中有两个 try/catch 结构,会导致生成内部错误(而实际上生成的代码是正确的)。(感谢 Fredrik Thulin。)
不正确的调用(例如
M:42()
)会导致编译器崩溃。编译器现在会生成警告。(感谢 Ulf Wiger。)自有 ID:OTP-5553
改进和新特性
新的
fun M:F/A
构造创建一个引用M:F/A
最新版本的函数。此语法旨在替换具有许多问题的元组函数{M,F}
。新的类型测试
is_function(Fun, A)
(可以在 guard 中使用)测试Fun
是否是可以应用A
参数的函数。(目前,Fun
也可以是元组函数。)自有 ID:OTP-5584
编译器 4.3.7
改进和新特性
进一步改进加密调试信息:为编译器提供新选项
encrypt_debug_info
。内部 ID: OTP-5541 辅助 ID: seq9837
编译器 4.3.6
修复的错误和故障
修复了生成代码的验证器 (beam_validator) 中的一个错误,该错误导致内部编译器错误,即使生成的代码实际上是正确的。
内部 ID: OTP-5481 辅助 ID: seq9798
改进和新特性
现在可以加密 Beam 文件中的调试信息,以帮助保持源代码的机密性。请参阅
compile
的文档,了解如何提供加密密钥,并参阅beam_lib
的文档,了解如何提供解密密钥,以便可以使用调试器、Xref 或 Cover 等工具。beam_lib:chunks/2
函数现在接受一个额外的 chunk 类型compile_info
,以便直接以 term 的形式检索编译信息。(感谢 Tobias Lindahl。)内部 ID: OTP-5460 辅助 ID: seq9787
编译器 4.3.5
修复的错误和故障
复杂的函数可能会导致编译器中的内部验证器生成内部错误,即使生成的代码是正确的。
内部 ID: OTP-5436 辅助 ID: seq9781
编译器 4.3.4
修复的错误和故障
在极少数情况下,可能会生成不正确的记录或元组访问代码。不正确的代码可能会触发编译器中的内部错误或在运行时引发异常。(感谢 Martin Bjorklund。)
修正了位语法匹配中的一个错误,其中子句可能会以错误的顺序匹配。(感谢 Ulf Wiger。)
内部 ID: OTP-5404 辅助 ID: seq9767
编译器 4.3.3
改进和新特性
在某些涉及 catch 的复杂上下文中给定位语法构造时,编译器会崩溃或由于内部一致性检查失败而终止。(感谢 Fredrik Thulin。)
诸如
<<103133:64/float>> = <<103133:64/float>>
的匹配过去会失败。现在它们会成功。函数头中的位语法匹配中变量的阴影,例如
L = 8, F = fun(<<L:L,B:L>>) -> B end
,编译器处理不正确。该函数过去被编译为 '>fun(<<8:8,B:8>>)
',而它应该以与fun(<<L:8,B:L>>)
相同的方式编译。修正了验证过程中的一个错误。当编译器通过重用代码来优化时,有时会发生此错误,该代码用于在从 catch 或 try-catch 语句中调用时引发异常。然后,验证器拒绝批准该代码,并抱怨
fun(<<L:L,B:L>>) -> B end
的处理方式与fun(<<L:8,B:L>>)
的处理方式不一致。unknown_catch_try_state 中的一个错误。
修正了优化器中的一个错误,该错误会导致编译器崩溃。(感谢 Peter-Henry Mander。)
现在,如果位语法构造由于类型不匹配(例如
<<an_atom:8>>
)而在运行时失败,则会生成警告。内部 ID: OTP-5342 辅助 ID: OTP-5118, OTP-5270, OTP-5323
诸如
t(<<A:8>> = <<A:8>)
的二进制模式匹配过去会在运行时静默失败(即永远不匹配)。现在,编译器会为此类模式生成错误。内部 ID: OTP-5371
编译器 4.3.2
修复的错误和故障
在极少数情况下,代码编译器可能会为元组匹配生成代码,如果传递的 term 不是元组,则可能会导致模拟器崩溃。
如果在 catch 中位语法构造失败,则先前分配的变量可能会获得错误的值。
现在,编译器会在生成的代码上运行验证过程,如果发现任何可疑代码,则会在写入 Beam 文件之前中止。特别是,验证过程会检查可能导致模拟器崩溃或模拟器中其他奇怪症状的不正确代码。
Richard Carlsson (HiPE) 对不受支持的参数化模块进行了一些更正。
内部 ID: OTP-5247 辅助 ID: OTP-5235
编译器 4.3.1
修复的错误和故障
更正了下面关于
try/catch
的发行说明。try/catch
在初始的 R10B 版本中有效。更正了一些小的代码生成问题。虽然生成的代码是正确的,但它比它需要的略微慢且更大。
删除了一个调试输出(在极少数情况下可见)。
not record_test(not_a_tuple, RecordTag)
和 guard 中的类似表达式将失败。新的选项
basic_validation
和strong_validation
用于快速检查模块的代码。如果
inline
选项出现在模块内的-compile()
指令中,则无法识别该选项。更正了未记录功能“参数化模块”中的一些错误。
内部 ID: OTP-5198
当使用未记录的功能“参数化模块”时,
?MODULE
宏无法正常工作。内部 ID: OTP-5224