C ++ - 初始化结构的有效方法

时间:2014-09-20 13:06:03

标签: c++ initialization

我和一位同事正在讨论将struct归零的某些方法的效率。我们假设我们有一个简单的struct,如此:

struct {
  int     iMyInt;
  char    cMyChar;
  double  dCoordinates[128];
} s_t;

我的方法是这样做:

s_t myStruct = { 0 };

我的同事改为采用这种方法:

s_t myStruct = { };

他注意到我的方法在两部分操作中初始化单个元素,然后初始化其余元素,而他的方法在一个部分操作中初始化整个struct,这个操作更快更多高效。

这是真的,如果是这样的话,所有编译器优化级别的情况总是如此(即:编译器是否会解决这个问题并为我优化它?)

谢谢。

2 个答案:

答案 0 :(得分:6)

首先,您发布的代码无效:您应该声明结构类型如下

struct s_t {
  int     iMyInt;
  char    cMyChar;
  double  dCoordinates[128];
};

那说:在你的具体情况下,两种方法是相同的,一切都是零。对于使用上述任何成员和/或数组元素的通用测试代码,-O3甚至-O0对于clang 没有差异-O0它甚至在两种情况下都会在整个结构上调用memset

s_t obj = {0};

movq    %rcx, %rdi
movl    %eax, %esi
callq   memset

s_t obj = {};

movq    %rcx, %rdi
movl    %eax, %esi
callq   memset

答案 1 :(得分:1)

C ++11§8.5.1/ 7:

  

如果列表中的初始化子条款少于聚合中的成员,那么每个成员   未显式初始化应从空初始化列表

初始化

最后一点C ++11§8.5.4/ 3:

  

否则[即。 T不是类,不是聚合,也不是引用],如果初始化列表没有元素,则对象是值初始化的。

对于像int这样的简单类型初始化值意味着零初始化。

因此,对于具有{0}值的类型,0的正式效果与{}的正式效果相同。

然而,标准不能规定编译器的实施质量。编译器可能会对文件名中的错误单词作出反应,并且只是在每次函数调用之前都会产生耗时的虚拟代码。同样地,它理论上可能会以不同的方式对待这两个符号。代码生成,即使它们的含义相同。


重温你同事的想法

  

他注意到我的方法在两部分操作中初始化单个元素,然后初始化其余元素,而他的方法在单部分操作中初始化整个结构更快更有效。

不,这只是对编译器如何工作的错误观点。

编译器无法正常工作。

但空括号表示法的优点在于它也适用于例如std::string以及T其中T()是有效表达式的任何其他类型T(0),但typedef struct Point_tag { int x, y; } Point; 不是。

即。它略胜一筹。


所有这些都说明,在C ++中没有必要进行C杂技

struct Point
{
    int x, y;
};

相反,你可以简单地做

{{1}}