在其定义中引用变量是合法的吗?

Is it legal to reference a variable in its definition?

本文关键字:变量 定义 引用      更新时间:2023-10-16
int test[2] = { 45, test[0] };
int x = (x = 111);
cout << test[0] << " " << test[1] << " " << x << "n"; // 45 45 111

前两行中的任务合法吗?Visual Studio 2010编译并运行它没有任何错误或警告,但似乎是一个奇怪的情况,可能是不确定的,因此我想确认它是可以接受的。Visual Studio确实会警告我,如果我像int x = x;这样的公然反身(可能是不确定的)做某事,所以我想知道似乎如何处理这些情况。

来自C 标准(C 11,但在C 98/03中没有区别):

(§3.3.2/1)名称的声明点 是在其完整声明器之后(第8条)和 initializer (如果有),[...] [示例:

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

在这里,第二个X用自己的(不确定)值初始化。 - 末尾示例]

这也适用于用户定义的类型以及数组类型。请注意,标准如何强调第二个示例中的x使用不确定值初始化。因此,没有办法知道以。

来初始化的值x

我会假设您在某个功能中,因为您在调用功能等。

testx的空间都分配在堆栈上。从理论上讲,这些家伙的空间应该在填充其价值之前就存在。如果我们查看生成的组件(x86 GCC),这是正确的。

subl    $40, %esp         # Add 40 bytes of memory to the current stack
movl    $0, -20(%ebp)     # Clear test[0] to 0
movl    $0, -16(%ebp)     # Clear test[1] to 0
movl    $45, -20(%ebp)    # Place the value of 45 into test[0]
movl    -20(%ebp), %eax  # Copy that 45 into a register
movl    %eax, -16(%ebp)  # Move that register's value (45) into test[1]
movl    $111, -12(%ebp)  # Assign x to be 111, optimize out the unnecessary duplicate assignment
    ... #continues on to set up and call printf

我们可以看到将40个字节添加到堆栈中。请注意,测试[0],Test [1]和X的地址如何以4个字节间隔(-20,-16,-12)从%ebp标记为连续地址。他们在内存中存在的位置存在,并且可以在定义的情况下访问而不会出错。编译器在这里将它们都清除为0,尽管我们可以看到这是不必要的。您可以删除这两行,但仍可以正常运行。

我们可以从此中绘制的是您的 int test [2] int x 可以在内部有任何数量的时髦圆形参考本身和代码将编译 - 确保您的参考获取良好的数据(即以某种方式初始化的数据)而不是您在这里完成的垃圾是您的工作。这也适用于其他情况 - 编译以组装并自己检查一下。

这是合法的,因为变量的声明是在您初始化时完成的。但是,test[1]的值不确定。

您拥有的所有代码都是完全合法的。甚至在某些情况下,您实际上甚至都希望也可以做。