【问题标题】:What are the default values of struct members in C?C中结构成员的默认值是什么?
【发布时间】:2016-06-16 11:22:11
【问题描述】:

假设都是局部自动变量

假设我有以下程序:

int x;
printf("%d",x);

编译器给了我警告:x is used uninitialized in this function。但是为什么我对结构成员不一样:

struct Person
    {
        int age;
        char name[10];
    } man;

printf("Name : %s Age : %d\n", man.name, man.age);

本地堆栈成员是否已初始化为某些默认值?我希望它们是垃圾值。如果是这样,为什么编译器在未初始化使用时不会为结构成员抛出警告?

【问题讨论】:

  • 仅仅因为您没有收到警告,这并不意味着您的代码不会调用未定义的行为。如果标准中有这样的要求,请说明对段落的引用。
  • 它们实际上包含垃圾值,这取决于您如何处理它们,因为有时这些“垃​​圾”设置在其他地方,因此它们实际上并不是“垃圾”
  • @Gar:不,它们仍然是“垃圾”。就称为 C 的抽象而言,它们具有未指定的值。仅仅因为您认为您将数据写入内存中的同一位置,并不意味着您将从该代码中获得可预测且定义明确的行为。
  • Variable default values的可能重复
  • @Gar:标准中没有使用“垃圾”一词是有充分理由的。它们有一个 indeterminate 值。

标签: c


【解决方案1】:

编译器不需要为此提供诊断。好的编译器可以。常规变量和结构没有什么不同,如果它们在本地范围内(自动存储持续时间),它们将包含垃圾值。使用这些值可能会引发未定义的行为。

唯一使结构不同的是,如果您至少初始化一个成员,其余成员将设置为零(初始化时就好像它们具有静态存储持续时间一样)。但是当没有任何成员被初始化时,情况就不是这样了。

【讨论】:

  • @Olaf:这个问题的代码中结构对象的未命名成员在哪里?
  • @Olaf 参见 6.7.9/21。 “如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。"
  • @Olaf 等等……你到底在说什么? §9 是关于“未命名成员”的,这意味着 填充字节。这与这个问题/答案无关。它在§9 中所说的只是您不能相信具有自动存储持续时间的对象的填充字节具有任何给定值。 “除非另有明确说明”是指在第 10 节中将填充字节静态初始化为零。有关填充字节的一些好的建议,请参阅 CERT-C EXP42-C
  • 嗯,看来我完全偏离了轨道。抱歉,我只使用指定的初始化程序,并且在阅读该段落时似乎有错误的关联。真丢人。再次抱歉!
  • @Lundin:以防万一删除我的 cmets 并且“对我感到羞耻”还不够:你是对的,我完全完全走错了路我不知道'不抽烟,所以我头上没有灰烬 :-) 其余的只是试图意识到 为什么 我错了。这有时可以帮助我避免第二次(或第三次……)落入同一个坑。感谢您让我正确!
【解决方案2】:

不,它们没有初始化为任何默认值。您可以说编译器以及标准缺乏检测此类问题的能力并且不提供任何警告。可能对于编译器编写者来说,检查普通(基本)数据类型很容易,而不是 UDT。

代码分析工具可能会在此类情况下发出警告。以 CppCheck 为例。

【讨论】:

  • 嗯...我是这么认为的。我提出这个问题只是为了确认,因为互联网上没有其他相关讨论。
  • @Insane Coder:以什么方式相关?讨论局部变量的初始化(或非初始化)?或者讨论编译器对这种情况发出(或不发出)警告?
  • “网上讨论”是一个非常广泛的话题 ;-)
  • @Insane 真的吗? stackoverflow.com/q/37636550/560648 stackoverflow.com/q/4179345/560648 是我在几秒钟内找到的第一对情侣
  • 只是补充一点,编译器甚至不需要检查标量。这只是一个有用的附加功能。
猜你喜欢
  • 2012-11-22
  • 2011-02-06
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 2010-11-07
相关资源
最近更新 更多