c++ - 初始化类成员的任何开销?
问题描述
假设我有以下代码
class C {
public:
explicit C() :
member()
{}
private:
int member;
};
我想member()
将我的变量值初始化member
为零。
我的问题是:这在运行时是否有任何开销?还是在编译时以某种特定方式完成?
解决方案
简而言之:开销很小,但编译器很聪明!
长版:
内存必须清零,这需要一些工作。您可以看到,当您将类编译为程序集时,还有一个简单的驱动程序函数
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
某个特定内存位置的 a 设置为零。DWORD
是 32 位的。
编译器可能能够组合初始化。例如,如果您添加第二个int
:
class C {
public:
explicit C()
: member(), anotherMember()
{}
private:
int member;
int anotherMember; // <====
};
int main() {
C c;
}
然后DWORD
更改为 aQWORD
所以它实际上一次将两个整数归零。即使使用更高的优化级别,您也会看到这一点,例如,当您添加一些编译器无法优化的内容时,例如读取stdin
并编译它-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;
然后你会看到零赋值将从输出中删除。
推荐阅读
- python - 在 Docker 容器中包含本地文件夹
- java - elasticsearch.service:主进程退出,code=exited,status=1/FAILURE
- rust - 为什么从 mp3 文件打印艺术家信息时会得到“\u{0}”?
- c# - 如何使用asp.net在当前html中显示另一个html?
- c++ - Boost 进程在新窗口中打开进程 (Windows)
- flutter - 创建一个观看列表的流?
- c# - 将一个类的多个属性聚合成一个字符串
- reactjs - 为什么我的 iframe 有时会在签署 DocuSign 表单之前首先加载返回 URL 页面?
- c# - 从我的方法中替换 IF 和 Else If 语句
- git - 使用 husky hook 强制推送到另一个远程分支