【问题标题】:Is this valid C? No warning about p being uninitialized这是有效的C吗?没有关于 p 未初始化的警告
【发布时间】:2011-07-13 08:27:26
【问题描述】:

使用 gcc (4.5) 和尽可能多的 -Wall、-Wextra、-Wuninitialized 类型标志编译此代码 sn-p 不会给我任何警告:

int main() {
    int *p = p;
    printf("p = %p\n", (void *)p);
    return 0;
}

但是多次运行它会得到这个输出:

p = 0xbe9ff4
p = 0x550ff4
p = 0xeb1ff4
p = 0x4caff4

...等等。

这是怎么回事?

编辑:使用“g++ -Wall”编译反而会给我警告:

In function ‘int main()’: warning: ‘p’ is used uninitialized in this function

【问题讨论】:

  • 看来你欺骗了编译器...
  • 我以前在某个地方见过这个。我不知道它是否有效,但肯定是未定义的行为。
  • 调用一个接受可变数量参数但范围内没有原型的函数是 UB。你的编译器可以为所欲为
  • @pmg:我认为更多的是关于自初始化。
  • 它在 C++ 中变得更好:stackoverflow.com/questions/2600152/…

标签: c gcc


【解决方案1】:
int *p = p;

p 在解析 int *p 后立即定义,但 RHS 仅在之后评估。该语句等价于

int * p;
p = p;

这在具有隐式构造函数的 C++ 中是不同的,但在普通的 C 中,这就是你所拥有的。未定义的初始值。

就编译器警告而言,这是一个实施质量问题。 gcc 没有被“欺骗”,它只是被允许。

【讨论】:

  • 你是对的,但如果我按照你的建议将语句分成两行,我确实会收到警告。
  • 所以 gcc 的警告逻辑存在差距。提交错误报告。
  • 编译器没有义务找出所有可能的警告。
  • 在法律意义上,它没有义务提供任何警告。然而,在道德意义上,它应该给出它所能发出的每一个警告。 </philosophy>
【解决方案2】:

Valgrind 给出关于 p 未初始化的警告。我猜是 gcc 被骗了,应该填写一个错误报告。

【讨论】:

  • 向 Valgrind 致敬以实际进行测试——但我不确定我是否会关心 gcc 错误报告.....
  • 我想没有理由不这样做——我只是觉得这太小众了,无法编写额外的代码......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2020-03-08
  • 2011-03-19
  • 2023-03-25
  • 2012-01-31
  • 2015-03-22
相关资源
最近更新 更多