int var = 1; void main(){int i = i; }

时间:2010-07-04 01:57:53

标签: c++

这是我的访谈问题:

int var = 1;
void main()
{
    int i = i;
}

分配后i的价值是多少?它真的是编译器依赖的还是仅仅是未定义的?我在cygwin上的g ++似乎总是给我0。

由于

5 个答案:

答案 0 :(得分:15)

i具有不确定的值,因为它未初始化。因此,它不仅依赖于编译器,而且还取决于该内存位置发生的任何情况。本地范围中的变量未在C ++中初始化。

我认为顶部不是int var = 1;,而是int i = 1;

仍然会使用本地范围i,因为变量的声明点紧跟在其声明符之后和初始值之前。

更具体地说,C ++ 03标准的第3.3.1-1节:

  

名称的声明点是   完成后立即   声明者(第8条)及其之前   初始化程序(如果有的话),除非另有说明   下面。   [实施例:

int x = 12;
{ int x = x; }
     

这里第二个x用它自己的(不确定的)值初始化。 ]


另一方面,我不认为这是一个非常好的面试问题,因为它与知道一些关于语言的模糊事实有关,而这些事实并没有说明你的编码经验。

答案 1 :(得分:3)

如果你真的是指你所说的代码,那么它是未定义的,因为int i = i;与仅仅执行int i;相同,这使它保持未初始化。但是,你可能意味着:

int i = 1;
void main() {
    int i = i;
}

i在本地范围内仍然未定义,但问题至少稍微有点兴趣。局部i一旦定义就会影响全局的i,所以当分配发生时,本地定义已经存在,而右侧i指的是定义的mainint i = 1;内,而不是全球。如果它没有删除全局int i = i;会导致编译错误,因为i会引用尚不存在的{{1}}

答案 2 :(得分:1)

这会导致未定义的行为,因为您在 i 的生命周期开始之前从其读取。

首先:

<块引用>

[basic.life]/1.2

... 对象的生命周期...开始于:

——它的初始化(如果有)完成

i读取时i的初始化没有完成,因为需要知道该值才能完成初始化。

下一步:

<块引用>

[basic.life]/7.1

... 在对象的生命周期开始之前但在对象将占用的存储空间已经分配之后...任何引用原始对象的泛左值都可以使用,但只能以有限的方式使用。 ... 程序有未定义的行为,如果:

——泛左值用于访问对象

i 读取确实“访问对象”,因此是 UB。

答案 3 :(得分:0)

为什么我在这里有任何价值,甚至未定义?作业没有任何作用,可以完全优化。

答案 4 :(得分:0)

我有同样的面试问题,我可以确认它确实是int var = 1;

这意味着这确实有所不同。我会运行代码,但我现在不在我的电脑上。

我同意像这样的问题对于面试来说是愚蠢的。通过类比,就好像有人正在面试厨师的工作一样,问题是“如果你给一个人喂了一勺大肠杆菌,淋上了伤寒,他们会病到多少?”。 你不太可能在工作中需要那些知识。