【问题标题】:Any overhead in initializing class members?初始化类成员的任何开销?
【发布时间】:2018-06-27 06:57:48
【问题描述】:

假设我有以下代码

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

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

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

【问题讨论】:

标签: c++


【解决方案1】:

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

长版:

内存必须清零,这需要一些工作。可以看到当你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;
}

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

mov dword ptr [rsp], 0

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

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

然后你会看到零赋值将从输出中删除。

【讨论】:

  • 关于问题中的 3 句话,您无法在发布答案之前花时间阅读的问题是什么TL;DR:TL;DR: 除了“我的答案可能不正确,因为我没有花时间阅读问题”之外,您的答案没有添加任何内容。 ——而且看起来很幼稚。因此,请避免在您的答案中过度使用可爱的首字母缩略词。 (除了那个尼特,不错的答案)
  • @DavidC.Rankin the TL;DR 不是关于问题,而是我的回答:它很长而且很详细,所以如果您不想阅读所有内容,“TL;DR”总结结论。我将删除令人困惑的首字母缩略词:-)
  • @CompuChip - 当涉及到单个机器指令时,我会犹豫是否将 Yes 加粗。尤其是当您在初始化多个变量时还显示您获得折扣时。 :-) 在(中等不错的)question the other day 中,我们注意到具有两个操作的循环与仅具有一行代码的循环具有相同的成本。在某些情况下,指令可以是“免费的”。
【解决方案2】:

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

比较成员初始化和不初始化的区别:
https://godbolt.org/g/ZE62PP vs https://godbolt.org/g/msRQtp

【讨论】:

    猜你喜欢
    • 2020-08-10
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 2016-08-02
    相关资源
    最近更新 更多