在C ++中,默认情况下,普通旧数据(POD)局部变量未初始化。我注意到,这会导致错误,因为尝试读取未初始化变量的值是未定义的行为。
有没有办法强制编译器自动初始化所有局部变量?也许是内置此功能的编译器,或者是GCC或Clang之类的常见编译器的编译器开关? Gnu扩展我会没事的;它不一定是标准的。
我希望变量是默认初始化的,这意味着int
将被设置为0.
我很无聊将所有本地int
和私有类字段分配给0。
答案 0 :(得分:1)
我不知道该做的任何事情,即使它 did 存在,它也只是一个“调试”功能,不能在生产代码中使用。
示例:电子围栏库可以选择将内存初始化为0或0xff
EF_FILL 当设置为0到255之间的值时,分配的内存的每个字节都会初始化为该值。这可以帮助检测未初始化内存的读取。设置为-1时,某些内存将填充为零(大多数系统为操作系统默认值),并且某些内存将保留上次使用时写入该内存的值。
(仅适用于已分配的内存,不适用于自动内存)。
依靠未定义为/未在标准中定义的开关将使您的代码不可移植。在某些时候,有人会使用您的代码在其他平台上交叉编译它,这将会失败。
作为帮助/保护措施,某些工具,例如Coverity(注意:我与该公司无关)可以检测代码中未初始化的POD成员。可能有免费的工具可以做到这一点。
那么如果有一个或两个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
之类的成员,...不透明
OR(可能有点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)
答案 1 :(得分:-1)
有人建议使用零个初始化的局部变量来编译linux内核,请参阅今年https://youtu.be/FY9SbqTO5GQ?t=742上linux.conf的演示文稿
为此,演示者团队使用了实验性的gcc开关finit-local-vars
,补丁位于https://gcc.gnu.org/ml/gcc-patches/2014-06/msg00615.html
我希望这将最终合并到gcc主分支并被广泛采用。从字面上看,我见过的每个代码样式指南都要求C / C ++编码人员在定义变量的任何地方进行明确的零赋值= 0
。这是容易出错且毫无意义的猴子工作。