3

考虑这段代码。

foo(int x, int y){
    x = y + 1;
    y = 10;
    x++;
}
int n = 5;
foo(n,n);
print(n);

如果我们假设该语言支持按值传递结果,那么答案是什么?据我所知,按值传递结果复制进出。但是我不确定n当它被复制到两个不同的形式参数时会是什么值。应该x并且y像参考一样行事?或者应该n得到x或者y取决于最后复制出来的值?

谢谢

4

1 回答 1

3

无论是普通的按值传递还是按值传递结果,然后xy将成为 的单独副本n它们绝不会相互关联,除非它们以相同的值开头。

然而,pass-by-value-result 在函数退出时将值分配回原始变量,这意味着n将采用xand的值y它首先得到哪个(或更重要的是,最后一个,因为这将是它的最终值)是开放的解释,因为你没有指定你实际使用的语言。

此条目上的 Wikipedia 页面对这个主题有这样的说法(“call-by-copy-restore”是您所问问题的术语,我已经强调了重要的一点并进行了解释以使其更清楚):

call-by-copy-restore 的语义也不同于 call-by-reference 的语义,其中两个或多个函数参数相互别名。也就是说,指向调用者环境中的同一个变量。

在引用调用下,写入其中一个会立即影响另一个;call-by-copy-restore 通过为函数提供不同的副本来避免这种情况,但根据首先复制回哪个别名参数,将结果留在调用者的环境中未定义。在入境和返回时,副本是否会以从左到右的顺序制作?

希望语言规范能够阐明实际的一致行为,以避免您在 C 和 C++ 中经常看到的所有未定义行为的角落:-)

检查下面的代码,对原始代码稍作修改,因为我天生懒惰,不想计算最终值:-)

foo(int x, int y){
    x = 7;
    y = 42;
}
int n = 5;
foo(n,n);
print(n);

我认为最有可能的直接可能性是:

  • 严格的从左到右复制退出,n将变为xthen y,所以42
  • 严格的从右到左复制退出,n将变为ythen x,所以7
  • 未定义的行为,n可能具有任何一个或任何一个值。
  • 如果编译器没有严格的规则并且不希望您的代码最终以(看似)随机的方式运行,则编译器会引发诊断并拒绝编译。
于 2019-05-01T08:05:09.057 回答