以下代码包含用于初始化自身的变量,我很难理解变量声明何时完成,并且即使它们在gcc中编译,其中一些也是非法的。
int main(void)
{
int a = a;
int b = (int) &b;
int c = c ? 1 : 0;
int d = sizeof(d);
}
答案 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
在初始化之前使用,可能导致未定义的行为。