为什么我得到 C 程序的垃圾值

Why am I getting garbage value for the C program?

本文关键字:程序 为什么      更新时间:2023-10-16

如果我使用 GCC/Clang 编译以下 C 代码,为什么我会得到垃圾值?请注意,如果我只是在内部范围内打印 x 的值,我会得到预期的结果。

#include<stdio.h>
int main()
{
    int x = 5;
    {
        int x = x;
        printf("%d", x);
    }
    return 0;
}

在此声明中

int x = x;

标识符x的声明点是在声明器的完整定义之后,该声明符x在赋值符号之前已经可见=并隐藏在外部块作用域中声明的具有相同名称的变量。

并且您有未初始化的x分配给自身。因此,它具有不确定的值。

你可以这样想象

int x;
x = x;

C++标准中存在完全相同的示例(3.3.2 声明点(

1 名称的声明点紧随其后 完整的声明符(第 8 条(及其初始值设定项(如果有(之前, 除非下文另有说明。[ 示例:

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

在这里,第二个 x 使用它自己的(不确定(值进行初始化。 —结束示例 ]

在C标准中有书面的(6.2.1标识符的范围(

7 结构、联合和枚举标记的作用域仅以 在声明 标记。每个枚举常量的作用域紧随其后 其定义枚举器在枚举器列表中的外观。任何 其他标识符的作用域在完成 它的声明符。

注意枚举器的定义。枚举器的规则是不同的。

该程序格式良好,枚举器x将由在外部作用域中声明的变量x初始化(而枚举器y将由前面的枚举器x初始化(。

#include <iostream>
int main()
{
    const int x = 10;
    {
        enum E { x = x + 1, y = x };
        std::cout << "E::x = " << x << ", E::y = " << y << std::endl;
    }
    std::cout << "x = " << x << std::endl;
}    

程序输出为

E::x = 11, E::y = 11
x = 10
声明

int x = 5;超出了第二个块的范围。这意味着变量x在以下代码段中

{
    int x = x;
    printf("%d", x);
}

不同于外部变量x,在main中声明。因此,当您尝试在赋值中访问其值时,它会给出一个垃圾值,因为它之前在此范围内不存在,因此未初始化