初始化类成员有任何开销吗?

时间:2018-06-27 06:57:49

标签: c++

假设我有以下代码

class C {
public:
  explicit C() :
     member()
  {}
private:
  int member;
};

我想将member()的值member初始化为零。

我的问题是:这在运行时会产生任何开销吗?还是在编译时以某种特定方式完成了?

2 个答案:

答案 0 :(得分:5)

简而言之:开销很小,但是编译器很聪明!

长版:

必须将内存清零,这需要一些工作。您可以看到compile your class to assembly以及简单的驱动程序功能

int main() { C c; } 

使用-O1优化。

然后,在没有成员初始化的情况下,生成的代码如下

main: # @main
  push rax
  mov rdi, rsp
  call C::C() [base object constructor]
  xor eax, eax
  pop rcx
  ret
C::C() [base object constructor]: # @C::C() [base object constructor]
  ret

在最后两行中,您看到构造函数是微不足道的。当您将成员初始化添加到方括号中时,它将变为

C::C() [base object constructor]: # @C::C() [base object constructor]
  mov qword ptr [rdi], 0
  ret

mov指令将某个特定内存位置的DWORD设置为零。 DWORD是32位。

编译器可以组合初始化。例如,如果您添加第二个int

class C {
public:
  explicit C()
     : member(), anotherMember()     
  {}
private:
  int member;
  int anotherMember; // <====
};

int main() {
    C c;
}

然后DWORD更改为QWORD,因此实际上将两个整数立即置零。即使在更高的优化级别下,您也将看到这种情况,例如,当您添加一些编译器无法优化的内容时,例如从stdincompile this with -O2

进行读取
#include <iostream> 

class C {
public:
  explicit C()
     : member()
  {}
  int member;
};

int main() {
    int x;
    C c;
    std::cin >> c.member;
}

然后,构造函数主体将内联到main函数中,但您仍会找到零指令

mov dword ptr [rsp], 0

还要注意,根据实例化之后的代码,编译器可能会进一步优化。例如,如果您查看

的输出
C c;
c.member = expression;

然后您将看到零分配将从输出中删除。

答案 1 :(得分:2)

这取决于编译器及其优化。假设优化级别为无,那么编译器很可能会生成一些用于初始化成员变量的指令。此代码已优化,例如对于使用-O1的gcc。

比较成员初始化和没有成员初始化之间的区别:
https://godbolt.org/g/ZE62PPhttps://godbolt.org/g/msRQtp