C++ c+中返回值优化生成的等价代码+;

C++ c+中返回值优化生成的等价代码+;,c++,C++,我无法理解编译器是如何在幕后对其进行优化的。i、 它生成的等效代码是什么? 中提到的示例显示了优化前的代码: struct Data { char bytes[16]; }; Data * f(Data * __hiddenAddress) { Data result = {}; // copy result into hidden object *__hiddenAddress = result; return __hiddenAddress; } int

我无法理解编译器是如何在幕后对其进行优化的。i、 它生成的等效代码是什么? 中提到的示例显示了优化前的代码:

struct Data { char bytes[16]; };

Data * f(Data * __hiddenAddress)
{
    Data result = {};
    // copy result into hidden object
    *__hiddenAddress = result;
    return __hiddenAddress;
}

int main()
{
    Data __hidden; // create hidden object
    Data d = *f(&__hidden); // copy the result into d
}

它并没有说优化的等效代码。好的,这一页已经被证明不够清晰,因为我在第一次扫描(oops)时误读了它。以下内容在优化前列为

struct Data { char bytes[16]; };
Data f()
{
  Data result = {};
  // generate result
  return result;
}

int main()
{
  Data d = f();
}
您列出的代码是未优化的伪版本,编译器可能会对此进行解释,并完成临时和复制构造。它显示的是编译器如何将返回值的函数(返回值传递机制)转换为过程代码

之后,优化后的代码仍然列出:

struct Data { char bytes[16]; };

void f(Data * p)
{
  // generate result directly in *p
}

int main()
{
  Data d;
  f(&d);
}

即:允许编译器直接处理返回值的目标,绕过函数体中临时实例的构造/销毁/复制。

好的,页面不太清晰,因为我在第一次扫描(oops)时误读了它。以下内容在优化前列为

struct Data { char bytes[16]; };
Data f()
{
  Data result = {};
  // generate result
  return result;
}

int main()
{
  Data d = f();
}
struct Data { char bytes[16]; };

void f(Data * useThisInsteadOfReturning)
{ 
   // update *useThisInsteadOfReturning directly
}

int main()
{
  Data d;
  f(&d); // use d in the function
}
您列出的代码是未优化的伪版本,编译器可能会对此进行解释,并完成临时和复制构造。它显示的是编译器如何将返回值的函数(返回值传递机制)转换为过程代码

之后,优化后的代码仍然列出:

struct Data { char bytes[16]; };

void f(Data * p)
{
  // generate result directly in *p
}

int main()
{
  Data d;
  f(&d);
}

即:允许编译器直接处理返回值的目标,绕过函数体中临时实例的构造/销毁/复制。

优化后的代码如下所示。引用维基百科网站:

struct Data { char bytes[16]; };

void f(Data * useThisInsteadOfReturning)
{ 
   // update *useThisInsteadOfReturning directly
}

int main()
{
  Data d;
  f(&d); // use d in the function
}
struct Data { char bytes[16]; };

void f(Data * p)
{
   // generate result directly in *p
}

int main()
{
   Data d;
   f(&d);
}

因此,编译器可以确定它有保留内存来保存函数的返回值,并将其视为指向该内存的指针已作为参数传递,并直接写入其中,而不是在函数内创建另一个临时对象,然后复制内存。

优化代码如下所示你提到的那个。引用维基百科网站:

struct Data { char bytes[16]; };

void f(Data * p)
{
   // generate result directly in *p
}

int main()
{
   Data d;
   f(&d);
}

因此,编译器可以确定它有保留内存来保存函数的返回值,并将其视为指向该内存的指针已作为参数传递,并直接写入其中,而不是在函数内创建另一个临时对象,然后复制内存。

不,这不对。这是编写的代码。提问者代码是没有优化的代码(但对它做了其他事情),它说“这会导致数据对象被复制两次。”在代码之后,你可能想再次阅读维基百科的文章。OPs代码片段可以在没有优化的情况下生成。不过,下面有一个优化的变体。显然,他的维基百科副本与我们的不一样。@lou:你说得对。我读了我期望的东西,读得太多了,看起来不太好。如果你能给你的答案加上几行解释,我会删除这一行。不,那不对。这是编写的代码。提问者代码是没有优化的代码(但对它做了其他事情),它说“这会导致数据对象被复制两次。”在代码之后,你可能想再次阅读维基百科的文章。OPs代码片段可以在没有优化的情况下生成。不过,下面有一个优化的变体。显然,他的维基百科副本与我们的不一样。@lou:你说得对。我读了我期望的东西,读得太多了,看起来不太好。如果你能在你的答案中添加几行解释,我将删除这一行。请注意,编译器不会使用默认构造函数来构建返回值,然后分配给它。它只需分配内存,然后在返回语句所在的位置构造对象。请注意,编译器不会使用默认构造函数来构建返回值,然后将其赋值。它只需分配内存,然后在返回语句所在的位置构造对象。