首页 > 解决方案 > 内存中类位置的成员是否依赖于类定义中类成员的位置?

问题描述

我有一部分连锁班

template <typename T> 
class Part
{
public:

part* prev;
part* next;
T data;
}

T 的大小现在未定义,我认为最好将它放在内存的末尾。

例如,如果我向右移动 8 个字节,那么我肯定会走到下一个类成员的开头(在 64 位系统上),如果我先放 T,那么我不知道我会在哪里去。我会影响类成员在内存中的位置,还是编译器会按照他的意愿做所有事情?

我可以帮助使用它吗?

标签: c++classmemory

解决方案


我不能肯定地说,因为它是在各种编译器之间实现定义的......

我将此添加到您的代码中:

template <typename T>
class Part {
public:
    Part* prev;
    Part* next;
    T data;
};

template<typename T>
Part<T> makeClass(T value) {
   Part<T> part{};
   part.data = value;
   return part;
}

int main() {
    auto p = makeClass(12);
    return 0;
}

我在之间测试了它x86-64 clang (trunk)x86-64 gcc (trunk)并且x64 msvc v19.24在编译器资源管理器上发现这里所有的编译器设置都设置为-std=c++17 -O3.

如果我们查看三者之间生成的程序集,我们会看到以下内容:

main:                                   # @main
        xor     eax, eax
        ret

海合会

main:
        xor     eax, eax
        ret

MSVC

part$ = 0
$T1 = 64
value$ = 72
Part<int> makeClass<int>(int) PROC       ; makeClass<int>, COMDAT
$LN3:
        mov     DWORD PTR [rsp+16], edx
        mov     QWORD PTR [rsp+8], rcx
        push    rsi
        push    rdi
        sub     rsp, 40                             ; 00000028H
        lea     rax, QWORD PTR part$[rsp]
        mov     rdi, rax
        xor     eax, eax
        mov     ecx, 24
        rep stosb
        mov     eax, DWORD PTR value$[rsp]
        mov     DWORD PTR part$[rsp+16], eax
        lea     rax, QWORD PTR part$[rsp]
        mov     rdi, QWORD PTR $T1[rsp]
        mov     rsi, rax
        mov     ecx, 24
        rep movsb
        mov     rax, QWORD PTR $T1[rsp]
        add     rsp, 40                             ; 00000028H
        pop     rdi
        pop     rsi
        ret     0
Part<int> makeClass<int>(int) ENDP       ; makeClass<int>

$T1 = 32
$T2 = 56
p$ = 80
main    PROC
$LN3:
        push    rsi
        push    rdi
        sub     rsp, 120                      ; 00000078H
        mov     edx, 12
        lea     rcx, QWORD PTR $T2[rsp]
        call    Part<int> makeClass<int>(int)      ; makeClass<int>
        lea     rcx, QWORD PTR $T1[rsp]
        mov     rdi, rcx
        mov     rsi, rax
        mov     ecx, 24
        rep movsb
        lea     rax, QWORD PTR p$[rsp]
        lea     rcx, QWORD PTR $T1[rsp]
        mov     rdi, rax
        mov     rsi, rcx
        mov     ecx, 24
        rep movsb
        xor     eax, eax
        add     rsp, 120                      ; 00000078H
        pop     rdi
        pop     rsi
        ret     0
main    ENDP

查看从各种编译器生成的程序集可能会帮助您确定代码中发生的情况及其数据对齐方式。在级别 3 使用优化器查看这些值后,将其更改为级别 2、1,然后是 1,然后查看生成的程序集的差异。这可能会给你一些见解!

来自专业人士的提示 - 相信你的编译器!


推荐阅读