将变量初始化为其自己的未定义值

Jan*_*Jan 21 c

在C中,将变量初始化为它自己的值是否有意义?如果是,那该怎么办?

请允许我详细说明.在Git源代码中,有一些例子可以将变量初始化为它自己的未定义值,如transport.cwt-status.c中所示.我从那些声明中删除了作业并运行了测试.看到没有回归,我认为这些任务是多余的.

另一方面,我用GCC 4.6和Clang 2.9进行了一些简单的测试.

#include <stdio.h>
int main() {
  printf("print to increase probability of registers being non-zero\n");
  int status = status;
  return printf("%i\n", status);
}
Run Code Online (Sandbox Code Playgroud)

使用-Wall -std=c99和各种-O级别进行编译不会显示任何警告并显示该信息status == 0.具有非零优化级别的Clang会打印一些垃圾值.这让我推断这些表达式的结果是不确定的.

我可以想象这样的赋值可以抑制未初始化的变量警告,但是从Git中获取的示例并非如此.删除分配不会引入任何警告.

这样的任务是不确定的行为吗?如果没有,你用它们做什么?


我已经建议在Git邮件列表上进行更改.这是我学到的.

Alo*_*ave 11

这是因为标准C99§6.2.1/ 7说:

任何不是结构,联合或枚举标记的标识符"都具有在其声明符完成后才开始的范围".声明符后跟初始化器.

但是,价值status不确定的.而且你不能依赖它被初始化为有意义的东西.

它是如何工作的?
int status为变量存在于堆栈(本地存储)上创建一个空间,然后进一步读取以执行status = status,status可能会初始化为堆栈帧中存在的任何值.

你怎么能防止这种自我初始化?
gcc提供了一个特定的设置来检测自我初始化并将它们报告为错误:

-Werror = uninitialized -Winit-self

为什么在此代码中使用它?
我认为在所述代码中使用的唯一原因是为ex:In transport.c控制未使用的变量警告,如果控件永远不会进入while循环,那么控制流cmp将不被使用且编译器必须生成警告为了它.同样的情况似乎是status变量wt-status.c

  • 我认为这个想法不是要抑制'未使用的变量'警告(你可以通过删除未使用的变量更简单地做到这一点),但是'(有时)在初始化之前使用'警告.这是一个小细节 - 它不会改变答案主要部分的有效性. (2认同)