2010-09-01 81 views
1

我不明白为什么代码在VS2010中打印'3'(发布版本),无论我是否留下'r'声明或将其注释掉。混淆输出?

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

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

所以,三个问题:

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

b。为什么即使存在'r'声明也打印3? (是否因为在C++中引用占用存储与否是实现定义的?)

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

回答

0

&arr1[1] - &arr2[0]

指针运算仅在同一阵列中明确定义。无论您认为此代码片段做了什么或应该做什么,都会调用未定义的行为。你的程序可以做什么

3

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

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

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

2

a。内存中变量的顺序是从

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

代码打印3因为它使用指针算术。减去& arr1 [1] from & arr2 [0]表示3个int的差值。

b。由于r从未被引用,因此C++编译器可以自由优化它。

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