【问题标题】:Does C language specify any implicit initialization for void pointers only?C 语言是否只为 void 指针指定任何隐式初始化?
【发布时间】:2015-08-25 06:27:43
【问题描述】:

这是我的代码:

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

将打印:

koraytugay$ ./a.out
0x7fff53b35ad0
0x0
koraytugay$ ./a.out
0x7fff5803fad0
0x0
koraytugay$ ./a.out
0x7fff512c9ad0
0x0
koraytugay$ ./a.out
0x7fff55213ad0
0x0
koraytugay$ ./a.out
0x7fff52dbdad0
0x0

语言中对此行为有什么解释吗?

【问题讨论】:

  • p 和 x 是未初始化的变量,标准规定使用未初始化的变量会导致未定义的行为。代码打印出未初始化的变量没有任何意义
  • 不。没有定义的解释。您的代码调用未定义的行为。您在 both 情况下评估 indeterminate 变量。
  • 是未定义的行为。你有什么问题?
  • @WhozCraig 你确定不确定的值会导致 C 中的 UB(而不是 C++)吗?
  • 我不认为它会调用未定义的行为,只是这些值在标准中是不确定的。然而,这些实现可能只是扩展了标准并且仍然符合标准。未初始化的局部变量,例如,在 MacOS 中总是归零(据我所知,出于安全原因),并且可能会欺骗您认为这只是一个普遍的事实。它不是。只有在 MacOS 中才会如此。

标签: c initialization void-pointers


【解决方案1】:

你问:

在 C 中,为什么空指针声明为 NULL,而其他类型包含垃圾?

这是使用小程序得出的错误结论。函数范围内未初始化的指针获得随机值。您不能依赖其值中的任何模式。

【讨论】:

  • @KorayTugay 它发生在你的系统和你的程序并不意味着它总是会在任何情况下发生,任何系统,任何编译器
  • @KorayTugay 重新排列您的打印语句 - 根据您的环境,您可能会得到“int 指针始终为 NULL”的印象(它们不是,它们只是未初始化)
  • @KorayTugay 这就是 UB 的意义所在。在我的系统上,交换两条打印线后,打印 p 会导致 NULL。
  • @KorayTugay 你看着一棵树,得出的结论是所有国家所有森林中的所有树都是一样的。
  • @AlanAu 其实我是在询问其他林务员我所做的观察,以便从有经验的人那里得到答案,而不是去寻找更多的 12341 棵树。
【解决方案2】:

我认为,C11 标准在这方面非常明确。参考第 6.7.9 章第 10 段,

如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。

现在,indeterminate 值是,嗯,indeterminate(您在这里指的是垃圾和/或 NULL)。你无法真正知道那里会发生什么。


编辑:

只是为了澄清,根据评论,

“但 void *p 似乎总是 NULL”

没错。 似乎。就C 标准而言,没有任何保证(指定)。

请注意:首选int main(void) 而不是int main()。推荐前者。

【讨论】:

  • 但是 void *p 似乎总是 NULL。
  • @KorayTugay 也许,但 C 对此没有说什么。也许是编译器扩展(只是猜测)。
  • 不确定的意思是,你不能依赖它,不是随机的。这取决于编译器。
  • 不管怎样,谢谢你的回答,当你问“简单”的问题时,人们似乎有点生气:)
  • @KorayTugay 好吧,有时,可悲的是,是的。
猜你喜欢
  • 1970-01-01
  • 2015-11-08
  • 2017-09-06
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多