我注意到几个影响很大的“未初始化标量变量”类型的 Coverity(静态分析工具)错误。其中很多只是未初始化的整数。
将它们初始化为零与默认情况下 C++ 所做的有什么不同吗?
C++ 是否自动将整数初始化为零?
对于自动变量:
一些编译器可能会这样做,但标准不需要它。符合要求的实现可能会使它们成为未初始化的垃圾值。
对于static
变量:
除非以其他方式显式初始化,否则它们必须初始化为零。
默认情况下,C++ 不会将整数变量初始化为零。
在调试模式下编译项目时,一些编译器可能会将它们归零或填充一些默认值。在通常不会发生的发布模式下。
静态变量有一个例外,但默认情况下,可以安全地假设任何未初始化的东西都包含一个随机值。
注意未初始化的变量。找到这种错误很难,而且会浪费很多时间。常见症状:程序在调试模式下工作正常,但在发布时表现异常。
在静态存储持续时间中声明的对象在任何其他初始化发生(包括默认初始化)之前初始化为零。
对类型对象进行默认初始化
T
意味着:
— 如果T
是(可能是 cv 限定的)类类型(第 9 条),则调用 的默认构造函数(如果没有可访问的默认构造函数T
,则初始化是非良构的); — 如果是数组类型,则每个元素都是默认初始化的; — 否则,不执行初始化C.11 §8.5¶6T
T
[ 注意:在任何其他初始化发生之前,每个静态存储持续时间的对象都会在程序启动时进行零初始化。在某些情况下,稍后会进行额外的初始化。—尾注 ]
C.11 §8.5¶9
是和不是。
这取决于它们是如何声明的。如果它们被声明static
,那么是的,它们被保证为零初始化。但是,函数中的局部变量可能不是零初始化的。在大多数情况下也不是类成员变量(例外是static
)。
基本上,如果不是static
,您应该假设它不会被初始化为 0。由于它没有被初始化,它可以具有任何值。
具有高影响的“未初始化标量变量”类型的错误
是的,它们的影响很大,因为未初始化的自动变量具有不确定的值,并且使用不确定的值是未定义的行为,因此如果您尝试在初始化之前从它们生成值,这些都是严重的错误。
将它们初始化为零与默认情况下 C++ 所做的有什么不同吗?
是的,对于自动标量变量,C++ 标准表示它们将具有不确定的值,来自8.5
[dcl.init]部分的 C++ 标准草案:
如果没有为对象指定初始化程序,则该对象是默认初始化的。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有一个不确定的值,如果没有对该对象执行初始化,该对象将保留一个不确定的值,直到该值被替换(5.17 [expr.ass])
编译器可能在调试模式下初始化局部变量,以帮助调试,我们可以看到MSVC 可以使用 /RTC 来做到这一点:
将局部变量初始化为非零值。这有助于识别在调试模式下运行时未出现的错误。[...]