令人困惑的输出?

时间:2010-09-01 14:35:22

标签: c++ reference

我无法理解为什么代码在VS2010(发布版本)中打印'3',无论是留下'r'的声明还是将其注释掉。

int main(){
    int arr1[2];
    int &r = arr1[0];
    int arr2[2];

    cout << (&arr1[1] - &arr2[0]);
}

所以,有三个问题:

一个。为什么代码打印3?

湾为什么即使“r”的声明存在,它也会打印3? (这是因为在C ++中,引用是否占用存储是否是实现定义的?)

℃。此代码是否具有未定义的行为或实现定义的行为?

3 个答案:

答案 0 :(得分:3)

因为在Release版本中删除了r变量。删除了未使用的内置类型变量,因为Release构建是通过优化完成的。稍后尝试使用它,结果会发生变化。有些变量可能被放入CPU寄存器而不是堆栈,这也会改变另一个局部变量之间的距离。

另一方面,未删除未使用的类实例,因为类实例创建可能有副作用,因为构造函数被调用。

这是未定义和实现定义的行为,因为编译器可以自由地将变量放在任何适当的位置。

答案 1 :(得分:2)

一个。内存中变量的顺序来自

arr2[0]
arr2[1]
arr1[0]
arr1[1]

代码打印3因为它使用指针算术。从&amp; arr2 [0]中减去&amp; arr1 [1]意味着3 int的差异。

湾由于r从未被引用,因此C ++编译器可以自由地对其进行优化。

℃。不是肯定的,但我不相信C ++标准定义了对堆栈变量的显式顺序。因此编译器可以自由地重新排序这些变量,甚至在它们看起来合适时在它们之间放置额外的空间。所以,是的具体实施。不同的编译器可以像答案一样轻松地给出-1。

答案 2 :(得分:0)

  

&arr1[1] - &arr2[0]

指针算法只能在同一个数组中定义良好。您认为此代码段的作用或应该做的并不重要,您正在调用未定义的行为。您的程序可以任何