为什么这个C代码编译?

Viv*_*ath 21 c variable-declaration

#include <stdio.h>
int main() {
    int c = c;
    printf("c is %i\n", c);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在定义一个名为的整数变量c,我将其值赋给自己.但这怎么可以编译呢?c尚未初始化,那么如何将其价值分配给自己呢?当我运行程序时,我明白了c is 0.

我假设编译器正在生成为c变量分配空间的汇编代码(当编译器遇到int c语句时).然后它接受未初始化空间中的任何垃圾值并将其分配回去c.这是发生了什么?

Bri*_*ndy 30

我记得在之前的回答中引用了这个,但我现在找不到它.

C++03§3.3.1/ 1:

名称的声明点紧跟在其完整的声明者(第8条)之后和其初始化者(如果有的话)之前,......

因此,变量c甚至可以在初始化器部分之前使用.

编辑:对不起,你特意问过C; 虽然我确信那里有一条等效线.James McNellis发现了:

C99§6.2.1/ 7:任何非结构,联合或枚举标记的标识符"都具有在其声明符完成后才开始的范围".声明符后跟初始化器.

  • C99§6.2.1/ 7:任何非结构,联合或枚举标记的标识符"都具有在其声明符完成后才开始的范围".声明符后跟初始化器. (12认同)

me_*_*and 11

你的猜测是完全正确的.int c将空间推送到变量的堆栈上,然后从该c = c部分读取并重新写入该变量(尽管编译器可以优化该变量).你的编译器正在推动值0,但不能保证始终如此.

  • 它可能不会推0,它恰好是现有的堆栈帧已经包含0内存.取决于0,当然是未定义的. (4认同)

Mat*_*hen 5

使用未初始化的值是未定义的行为(§C99J.2"具有自动存储持续时间的对象的值在不确定时使用").所以任何事情都可能发生在从鼻子恶魔到c = 0,到玩Nethack.