【发布时间】:2010-09-15 16:45:12
【问题描述】:
在我们的代码中,我们曾经有这样的东西:
*(controller->bigstruct) = ( struct bigstruct ){ 0 };
这曾经很好用,然后我们升级了 GCC 版本,突然开始看到堆栈溢出。查看程序集,旧的 GCC 代码(2.x)基本上是这样做的:
memset(controller->bigstruct, 0, sizeof(struct bigstruct));
新的 GCC (3.4.x) 正在这样做
struct bigstruct temp = { 0 };
controller->bigstruct = temp;
查看 C99 规范后,我明白了原因; C99 基本上要求堆栈上存在匿名结构。这是一个很好的概念,但这个结构有 4 MB 大,而且只打算存在于堆上!
我们采用了我们自己的“初始化”函数来显式设置成员,但这很丑陋,而且维护起来很头疼。我不认为 memset 是一个合适的解决方案,因为我不知道 0 的位值是该类型的适当零值(挑剔,我知道,但你在那里;我不介意编译器会这样做,因为它可以知道)
初始化这样一个大型结构的“正确”或至少是最好的方法是什么?
进一步澄清为什么我认为 memset 不是解决方案:未显式初始化的成员的初始化规则与静态初始化相同,如下所示: - 如果是指针类型,则初始化为空指针; - 如果它具有算术类型,则将其初始化为(正或无符号)零; ...
'memset' 会将内存设置为位模式零,这不一定是同一件事。想象一个不使用 IEEE 浮点数的系统。不寻常,但受 C 语言支持。0.0 的表示不一定意味着“所有位为零”,它可以是任何方便处理器的东西。
【问题讨论】:
-
如果我可能会问,你的结构中究竟是什么,它有一个占用 4MB 的定义? ://
-
什么样的平台不支持 IEEE 浮点并让你分配一个 4MB 的结构?
-
使用静态怎么样?静态结构 bigstruct Zero_bigstruct = { 0 };和 *(controller->bigstruct) = Zero_bigstruct; ?