C语言中的原始类型默认初始化为什么?

8
我刚刚让苹果的C/C++编译器将一个浮点数初始化为非零值(大约是“-0.1”)。这让我很惊讶,而且只有偶尔发生(但如果您先运行相同的函数调用/参数,就会100%地重复发生)。使用断言花费了很长时间来跟踪它。
我原以为浮点数被初始化为零。谷歌搜索表明我在想C++(当然,它对这些东西更精确 - 参见SO:C ++中的原始类型默认初始化为什么?)。
但也许苹果的借口是他们的编译器在C模式下运行...那么:C怎么样?应该发生什么,(更重要的是)什么是典型的?
(当然,我应该手动初始化它 - 我通常这样做 - 但在这种情况下,我失败了。虽然我没有预料到它会崩溃!)
(谷歌对于任何关于此的讨论都毫无用处 - 它们当前的搜索拒绝显示“C”而不包括“C ++”。它一直认为我太蠢,并忽略了我的输入,即使在高级模式下运行也是如此)
这是发生问题的实际源示例。起初,我认为可能存在MAX和ABS的定义问题(也许MAX(ABS,ABS)并不总是做您期望的事情?)...但是通过断言和调试器挖掘,我最终发现它是缺少初始化 - 那个浮点数极少情况下被初始化为非零值:
float crossedVectorX = ... // generates a float
float crossedVectorY = ... // generates a float

float infitesimal; // no manual init
float smallPositiveFloat = 2.0 / MAX( ABS(crossedVectorX), ABS(crossedVectorY));

// NB: confirmed with debugger + assertions that smallPositiveFloat was always positive

infitesimal += smallPositiveFloat;

NSAssert( infitesimal >= 0.0, @"This is sometimes NOT TRUE" );

取决于“初始化”发生的位置 - 可能根本没有被初始化。 - Mat
添加了我看到问题源代码的复制/粘贴。在我看来,它应该已经被初始化了吧? - Adam
1
+1 鼓励提问那些每个人都应该知道答案的问题。 - borrrden
5个回答

18

只有具有静态存储期的对象在没有显式初始化器的情况下才被初始化为0

#include <stdio.h>

float f;         // initialized to 0, file scope variables have static storage
static float g;  // initialized to 0

int main(void)
{
    float h;  // not initialized to 0, automatic storage duration
    static float i;  // initialized to 0

    return 0;
}

自动存储期对象(例如上面示例中的h)如果没有明确初始化,则具有不确定的值。 读取它们的值是未定义行为。

编辑: 为了完整起见,自C11以来,具有线程存储期的对象如果没有显式初始化也将被初始化为0


2
谢谢。这里有很多好的答案,但在我看来,像这样排列最容易一眼理解。 - Adam
@ouah 对象怎么样? - Abhishek Mane

9
标准的相关部分是§6.7.9第10段:
如果一个具有自动存储期的对象没有被显式初始化,其值是不确定的。
如果您的变量具有线程或静态存储期,则该段落的下一部分将生效:
如果具有静态或线程存储期的对象未显式初始化,则: -- 如果它具有指针类型,则初始化为null指针; -- 如果它具有算术类型,则初始化为(正或无符号)零; ...
我还要注意到您应该打开编译器的警告(特别是未初始化变量的警告),因为这应该立即为您识别出问题。

5
静态变量会被初始化为零,但我猜你说的是局部变量(即栈或自动变量) - 这些变量不会被初始化,而是得到该内存上堆栈中的任何值。

1

我不得不翻阅我的K&R来回答这个问题:

如果没有显式初始化,外部和静态变量保证被初始化为零;自动和寄存器变量具有未定义的(即垃圾)初始值。


0

我不相信C语言的任何标准都会定义变量的初始值。这符合C语言的一般哲学和应用领域——为成年人编程,他们可能有理由希望编译器不为他们初始化变量,并且知道初始化自己的变量是他们的责任。


2
如其他地方所提到的,文件和全局变量默认情况下会被初始化为零。 - Kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接