在范围内,所有声明都会在编译后在函数的开头发生(在C中)?

时间:2011-02-02 12:49:26

标签: c compilation declaration

在范围内,所有声明是否会在编译后在函数的开头发生(在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

2 个答案:

答案 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;
}