变量声明的完成点

时间:2015-11-26 16:23:32

标签: c initialization declaration definition

以下代码包含用于初始化自身的变量,我很难理解变量声明何时完成,并且即使它们在gcc中编译,其中一些也是非法的。

int main(void)
{
    int a = a;
    int b = (int) &b;
    int c = c ? 1 : 0;
    int d = sizeof(d);
}

4 个答案:

答案 0 :(得分:2)

在您的代码中

int a = a;

是UB,因为你正在阅读一个不确定的值。

int b = (int) &b;

将编译正常,因为,变量已经分配了内存,但标准不保证int能够保存指针的值。因此,从技术上讲,这也将转到UB。

int c = c ? 1 : 0;

是UB的原因与第一个相同。

int d = sizeof(d);

很好,因为在这种情况下,sizeof在编译时被评估,值是编译时常量。

答案 1 :(得分:1)

这个概念在C ++标准(3.3.2声明点)中有更好的描述,在C标准中具有相同的含义

  

1名称的声明点紧随其后   完整声明者(第8条)和在其初始化程序之前(如果有),   除非如下所述。

[ Example:
int x = 12;
{ int x = x; }
  

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

在您在此声明中显示的代码示例中

int a = a;

变量a由其自身初始化。所以它具有不确定的价值。

本声明

int b = (int) &b;

是有效的,变量b具有实现定义的值。

此声明

int c = c ? 1 : 0;

实际上相当于第一个声明。变量c具有不确定的值。

此声明

int d = sizeof(d);

有效,因为运算符sizeof中使用的表达式未被评估。

答案 2 :(得分:1)

参见C11规范中的第6.2.1节标识符范围。变量的范围在其声明者完成之后开始。有关声明符的含义,请参阅第6.7.6节声明符。请注意,初始值设定项(如果存在)位于声明符之后,因此声明的变量位于初始化程序中的范围内。有关声明的语法,请参见第6.7节声明初始值设定项 init-declarator 的一部分,其定义为

init-declarator:
     declarator
     declarator = initializer

答案 3 :(得分:0)

int a = a;  

a的定义发生在评估a和初始化之前。第二和第四个声明也是如此,除了第一个和第三个声明将调用未定义的行为..

如果是

int c = c ? 1 : 0;  

问题是变量c在初始化之前使用,可能导致未定义的行为。