rad*_*row 2 macros erlang preprocessor
我正在用 Erlang 编写一些应该在各种 OTP 版本上编译的模块。在某些情况下,我想使用旧版本中不受支持的++操作符模式,但前提是它可用。因此,我对这项任务的尝试如下:
f([]) -> empty;
f([_|_]) -> cons;
-if(?OTP_RELEASE >= 23).
f([] ++ _) -> empty_append;
-endif.
f(X) -> error(nah).
Run Code Online (Sandbox Code Playgroud)
我发现的这个问题的解决方法是:
将 iffed 子句移到开头。然而,这在以下情况下效果不佳:
-ifs创建一个美丽的 ifelses 花园,并多次复制整个函数。显然,这不会通过。
有什么方便的方法吗?如果可能的话,我希望有一个通用的解决方案,不限于所呈现的情况。
来自宏中的流控制:
The macro directives cannot be used inside functions.所以如果你想使用-ifdef你需要多次复制相同的功能。
(我想这与它们被定义在-和之间有关.)
话虽如此,您可以执行以下操作:
f([]) -> empty;
f([_|_]) -> cons;
f([] ++ _) when ?OTP_RELEASE >= 23 -> empty_append;
f(X) -> error(nah).
Run Code Online (Sandbox Code Playgroud)
您可以使用 验证从生成的梁 ASM 代码中删除永远不会匹配的子句erlc -S <module>。此外,编译器将显示警告。
在此步骤中产生的警告不能有选择地省略。从这里:
Another class of warnings is generated by the compiler during optimization and code generation. They warn about patterns that will never match (such as a=b), guards that always evaluate to false, and expressions that always fail (such as atom+42).
Those warnings cannot be disabled (except by disabling all warnings).
Run Code Online (Sandbox Code Playgroud)
如果你想完全避免警告,你需要类似的东西(请注意,这种风格不会删除分支,因为它):OtpRelease是一个变量
Another class of warnings is generated by the compiler during optimization and code generation. They warn about patterns that will never match (such as a=b), guards that always evaluate to false, and expressions that always fail (such as atom+42).
Those warnings cannot be disabled (except by disabling all warnings).
Run Code Online (Sandbox Code Playgroud)
编辑:在最后一个示例中,OTP23 的代码优化器能够删除无法访问的代码。在这种特殊情况下,如果f/2不导出,则其第 3 个或第 4 个子句将被删除,具体取决于?OTP_RELEASE)