在范围内,所有声明是否会在编译后在函数的开头发生(在C中)?以下示例显示了我想知道的更好一点。如果“ptr1”出现问题,我可以假设ptr2已初始化为NULL吗?
int main()
{
int ret = 0;
void * ptr1 = NULL;
if (ret = do_ptr_work(ptr1))
goto done;
void * ptr2 = NULL;
if (ret = do_ptr_work(ptr2))
goto done;
done:
if (ptr1) {
free(ptr1);
ptr1 = NULL;
}
if (ptr2) {
free(ptr2);
ptr2 = NULL;
}
return ret;
}
谢谢, Chenz
答案 0 :(得分:3)
没有。初始化定义为在达到声明时发生。如果跳过初始化,变量存在但未初始化。
C标准的一个相关部分是§6.2.4:
如果指定了初始化 对象,每次执行 宣言是在 块的执行;否则, 价值每次变得不确定 宣言已经达成。
(请注意,此文本仅适用于自动存储持续时间的对象)。另一个是§6.8:
具有的对象的初始化器 自动存储持续时间,和 可变长度数组声明符 具有块范围的普通标识符, 被评估,价值观 存储在对象中(包括 存储不确定的值 每个没有初始化器的对象 时间到达声明了 执行的顺序,好像它是一个 声明,并在每个声明中 按声明者出现的顺序。
答案 1 :(得分:0)
就我个人而言,我完全避免使用这种方法,因为它似乎与我喜欢的未定义行为太接近,并且当你转移到不同的编译器/平台或者只是当你混淆维护时它肯定会引起问题程序员。
为什么不在范围的开头声明变量? 无论如何,看起来更贴近我的眼睛。
int main()
{
void * ptr1 = NULL;
void * ptr2 = NULL;
int ret = 0;
if (ret = do_ptr_work(ptr1))
goto done;
if (ret = do_ptr_work(ptr2))
goto done;
done:
if (ptr1) {
free(ptr1);
ptr1 = NULL;
}
if (ptr2) {
free(ptr2);
ptr2 = NULL;
}
return ret;
}
或者甚至只是完全重构以删除goto?
int main()
{
void * ptr1 = NULL;
void * ptr2 = NULL;
int ret = do_ptr_work(ptr1);
if (!ret)
ret = do_ptr_work(ptr2);
// Tidy up...
if (ptr1) {
free(ptr1);
ptr1 = NULL;
}
if (ptr2) {
free(ptr2);
ptr2 = NULL;
}
return ret;
}