具名返回值优化 (NRVO)
注意: 本节文档仅描述当前的实现。这部分语言规范将会有变动。 详情查看链接 https://github.com/nim-lang/RFCs/issues/230 。
在例程内部返回值以特殊的 result 变量出现。这为实现与 C++ 的 “具名返回值优化” (NRVO) 类似的机制创造了条件。 NRVO 指的是 p 内对 result 的操作会直接影响 let/var dest = p(args) (定义 dest) 或 dest = p(args) (给 dest 赋值) 中的目标 dest 。 这是通过将 dest = p(args) 重写为 p’(args, dest) 来实现的,其中 p’ 是 p 的变体,它返回 void 并且接收一个与 result 对应的可变参数。
不太正式的示例:
proc p(): BigT = ...
var x = p()
x = p()
# 上面这段代码大致上会被解释为以下代码
proc p(result: var BigT) = ...
var x; p(x)
p(x)
假设 p 的返回值类型为 T。 当 sizeof(T) >= N (N 依赖于具体实现) 时,编译器就会使用 NRVO。 换句话说,NRVO 适用于 “较大” 的结构体。
即使 p 可能抛出异常,依然会使用 NRVO。这会带来显著的不同行为:
type
BigT = array[16, int]
proc p(raiseAt: int): BigT =
for i in 0..high(result):
if i == raiseAt: raise newException(ValueError, "interception")
result[i] = i
proc main =
var x: BigT
try:
x = p(8)
except ValueError:
doAssert x == [0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0]
main()
编译器能够检测这些情况并发出警告,但是这个行为默认是关闭的。通过 warning[ObservableStores] 以及 push/pop 编译指示可以为一段代码打开这个警告。以上面的代码为例:
{.push warning[ObservableStores]: on.}
main()
{.pop.}
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .