在 C++ 中,普通旧数据 (POD) 局部变量默认未初始化。不过,我注意到这会导致错误,因为尝试读取未初始化变量的值是未定义的行为。
有没有办法强制编译器自动初始化所有局部变量?也许是一个内置了这个特性的编译器,或者一个常见编译器的编译器开关,比如 GCC 或 Clang?我可以使用 Gnu 扩展;它不必是标准的。
我希望变量是默认初始化的,这意味着 anint
将设置为 0。
我厌倦了将所有 localint
和私有类字段分配给 0。
在 C++ 中,普通旧数据 (POD) 局部变量默认未初始化。不过,我注意到这会导致错误,因为尝试读取未初始化变量的值是未定义的行为。
有没有办法强制编译器自动初始化所有局部变量?也许是一个内置了这个特性的编译器,或者一个常见编译器的编译器开关,比如 GCC 或 Clang?我可以使用 Gnu 扩展;它不必是标准的。
我希望变量是默认初始化的,这意味着 anint
将设置为 0。
我厌倦了将所有 localint
和私有类字段分配给 0。
我知道没有开关可以做,即使它确实存在,它也只是一个“调试”功能,不能在生产代码中使用。
示例:电子围栏库具有将内存初始化为 0 或0xff
EF_FILL 当设置为 0 到 255 之间的值时,分配的内存的每个字节都被初始化为该值。这可以帮助检测未初始化内存的读取。当设置为 -1 时,一些内存用零填充(大多数系统上的操作系统默认值),一些内存将保留上次使用期间写入它的值。
(仅适用于分配的内存,不适用于自动内存)。
依赖未定义为/在标准中的开关会使您的代码不可移植。在某些时候,有人会使用您的代码在其他平台上交叉编译它,这将失败。
作为一种帮助/保护措施,像Coverity 之类的工具(注意:我不隶属于这家公司)可以检测代码中未初始化的 POD 成员。可能有免费的工具可以做同样的事情。
因此,如果有一个或 2 个 POD 成员(c++11),我会怎么做:
class Foo
{
...
private:
int x = 0;
int y = 0;
};
如果你有无数个成员,也许可以创建一个 POD 类/结构,创建 1 个具有这种类型的成员,并使用最有效的初始化方法将其初始化为 0:
class Foo
{
...
private:
struct Pod
{
int x,y,z,whatever;
};
Pod m = {0};
};
这迫使访问成员m.x
......不透明
或者(可能有点hacky但有效),创建一个POD结构,然后从中继承你的类。您现在可以memset
在默认构造函数中应用 POD 结构的大小
struct Pod
{
Pod()
{
std::memset(this,0,sizeof(Pod));
}
int x,y,z,whatever;
};
class Foo : private Pod
{
public:
...
private:
std::string name;
std::vector<int> elements;
};
该sizeof(Pod)
值确保memset
仅将 的成员设置Pod
为 0。
如果Pod
来自无法更改的 C 结构,则可以memset
在构造函数中移动语句Foo
,保持sizeof(Pod)
有一个建议用零初始化局部变量编译 linux 内核,参见今年 linux.conf 的介绍https://youtu.be/FY9SbqTO5GQ?t=742
为了做到这一点,演示者团队使用了一个实验性 gcc 开关finit-local-vars
,补丁在这里https://gcc.gnu.org/ml/gcc-patches/2014-06/msg00615.html
我希望这最终会合并到 gcc 主分支并被广泛采用。从字面上看,我见过的每个代码风格指南都要求 C/C++ 编码人员= 0
在定义变量的任何地方进行显式零赋值。这是容易出错且毫无意义的猴子工作。