gpt4 book ai didi

c++ - c++ 类实例成员是如何在机器级别传递的?

转载 作者:行者123 更新时间:2023-11-30 04:04:14 25 4
gpt4 key购买 nike

我了解类实例成员的基本布局(给定一个典型的c++实现),但是假设你有一个带有int num的MyClass作为成员,你创建了它的一个实例,这个成员在内存中的具体地址是怎样的在运行时处理?我会用一个例子更清楚:

class MyClass
{
int num;
int num2;
int num3;
public:
void setNum(); //always sets num to 10
};

然后你调用setnum,它怎么知道把哪 block 内存设置为10呢?MyClass 的内存布局可能看起来像

class MyClass size(12):
+---
0 | num
4 | num1
8 | num2
+---

那么它是否像当使用指向您的 myclass 实例的隐藏指针调用 setNum 以进行成员访问时一样简单,它是基于 offest 编写的吗?例如 myclasspointer+4?

编辑澄清它是如何决定写到哪里的?失败的复制粘贴将 vftable 留在了那里。我完全可以想象它只是一个已知的偏移量,对吧?

还是更复杂的东西?

为不清楚的术语道歉,我很少知道如何正确地表达问题......

最佳答案

编译器会知道 class 的内容(或 struct ),最重要的是不同成员变量的偏移量。 setNum函数被赋予 this指针作为“隐藏”参数,编译器将采用 this变量并添加 num 的偏移量.

具体如何发生取决于编译器。在 LLVM 中,它将使用 getelementptr VM 指令,它了解结构并在给定基地址的情况下添加索引给定的偏移量。然后,这将转换为某种采用 this 的指令。并且在一条指令中直接添加偏移量,或者在两条指令中加载指针然后添加偏移量——这在一定程度上取决于体系结构,以及下一条指令“需要”的内容。

num member 是结构中的第一个成员,它将是零,所以在 x86-64 上,用 clang++ -O1 编译,我们得到这个反汇编:

_ZN7MyClass6setNumEv:                   # @_ZN7MyClass6setNumEv
movl $10, (%rdi)
retq

换句话说,将数字 10 移动到 this 的地址中(在 %rdi - Linux 机器上的第一个参数)。

LLVM IR 更好地展示了发生的事情:

%class.MyClass = type { i32, i32, i32 }

; Function Attrs: nounwind uwtable
define void @_ZN7MyClass6setNumEv(%class.MyClass* nocapture %this) #0 align 2 {
entry:
%num = getelementptr inbounds %class.MyClass* %this, i64 0, i32 0
store i32 10, i32* %num, align 4, !tbaa !1
ret void
}

该类包含 3 i32 (32 位整数),并且该函数采用 this指针,然后它使用 getelementptr获取第一个元素(元素 0)。是的,比您预期的要多一个论点。这就是 LLVM 的工作原理;)

然后将值 10 存储到 %num 中计算地址。

如果我们更改 setNum 中的代码这样它将 10 存储到 num2 中相反,我们得到:

define void @_ZN7MyClass6setNumEv(%class.MyClass* nocapture %this) #0 align 2 {
entry:
%num2 = getelementptr inbounds %class.MyClass* %this, i64 0, i32 2
store i32 10, i32* %num2, align 4, !tbaa !1
ret void
}

注意最后一个数字变成了getelementptr .

汇编代码变成:

_ZN7MyClass6setNumEv:                   # @_ZN7MyClass6setNumEv
movl $10, 8(%rdi)
retq

(就目前而言,在原始问题的修订版 2 中,您的类 MyClass 的大小为 12、3 * 4 字节,而不是像您的文字所说的 8)。

关于c++ - c++ 类实例成员是如何在机器级别传递的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23864837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com