gpt4 book ai didi

c++ - 返回嵌套对象的成员有什么惩罚吗?

转载 作者:行者123 更新时间:2023-11-30 02:53:44 24 4
gpt4 key购买 nike

考虑以下代码,关于成员的嵌套访问:

struct A
{
size_t m_A;
};
struct B
{
A m_A_of_B;
};
class D
{
B instance_B;
A instance_A;
size_t m_D;
public:
size_t direct (void) { return m_D; }
size_t ind1 (void) { return instance_A.m_A; }
size_t ind2 (void) { return instance_B.m_A_of_B.m_A; }
};

我可以想象这里有两种不同的情况:

1。没有区别

根据我的理解,应该没有区别,因为所有函数都返回一个值,该值在类内存布局中具有与 this/相关的编译时常量位置。

我希望编译器能够识别它。

因此,我假设从我上面显示的(或更深的)此类嵌套结构返回成员不会受到惩罚。

2。指针间接

可能整个“间接”都是在这里进行的。例如在 ind2 中:

获取这个 -> 获取 instance_B 的相对位置 -> 获取 m_A_of_B 的相对位置 -> 返回 m_A


问题

  1. 嵌套访问的处理方式与编译器相关吗?
  2. 这三个功能有什么区别吗?

我问这个问题是因为我只是根据我对事物运作方式的了解对这个问题做出假设。因为我的一些假设在过去被证明是错误的,所以我想在这里问清楚。

如果有人问过这个问题,请原谅,如果可能的话,请指出适当的答案。

PS:您无需就“过早优化是万恶之源”或关于分析给出任何提示。我可以使用我正在开发的编译器来分析这个问题,但我的目标程序可以使用任何符合标准的编译器进行编译。因此,即使我无法确定任何差异,它们可能仍然存在。

最佳答案

标准对此没有限制。编译器编写器例如,一个真正扭曲的头脑可能会产生一个循环它在每个函数的开始什么都不做,用循环次数取决于循环次数函数名称中的字母。完全符合,但是......我宁愿怀疑他的编译器会有很多用户。

在实践中,(勉强)可以想象编译器计算出每个子对象的地址;例如在英特尔上,做类似于:

D::direct:
mov eax, [ecx + offset m_D]
return

D::ind1:
lea ebx, [ecx + offest instance_A]
mov eax, [ebx + offset m_D]
return

D::ind2:
lea ebx, [ecx + offset instance_B]
lea ebx, [ebx + offset m_A_of_B]
mov eax, [ebx + offset m_D]
return

事实上,我见过的所有编译器都可以计算出直接包含的对象的完整布局,并且会生成如下内容:

D::direct:
mov eax, [ecx + offset m_D]
return

D::ind1:
mov eax, [ecx + offset instance_A + offset m_D]
return

D::ind2:
mov eax, [ecx + offset instance_A + offset m_A_of_B + offset m_D]
return

(方括号中的偏移量相加发生在汇编程序;表达式对应于一个常量在实际可执行文件的指令中。)

所以在回答您的问题时:1 是它完全依赖于编译器,2是在实际操作中,会有绝对没有区别。

最后,您的所有函数都是内联的。而且它们很简单足以让每个编译器内联它们,至少在任何激活的优化程度。一旦内联,优化器可能会找到额外的优化:它可能能够检测到您使用 D::instance_B::m_A_of_B::m_A 初始化了例如,常数;在这种情况下,它只会使用常量,并且永远不会有任何访问权限。实际上,你担心这种优化水平是错误的,因为编译器会比你更好地为你处理。

关于c++ - 返回嵌套对象的成员有什么惩罚吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17680919/

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