Почему НРВО здесь не применяется?

NRVO не применяется, когда я запускаю этот код в VS2010.

#include <stdio.h>

class A
{
public:

A() { printf( "I am in constructor\n" ); }
A(const A& a) { printf( "I am in copy constructor\n" ); }
~A() { printf( "I am in destructor\n" ); }
int i;
};

A f(int j)
{
A a;
if ( j )  return a;
a.i = j;
return a;
}

int main()
{
A a;
a = f(5);
}

Изменить: это как-то связано с деструктором. Когда я закомментирую его строку, используется NRVO. Но почему это?

5

Решение

Почему НРВО здесь не применяется?

Если это просто ваше любопытство, и вы хотите знать, как VC10 алгоритмически решает, следует ли выполнять NRVO, то единственные люди, которые могут надежно ответить на этот вопрос, это те, кто знает, как работает VC10 внутри, — те, кто его написал.

Для чего я могу сказать, согласно C ++ 11 Standard компилятор позволено выполнить NRVO в этой ситуации, и не делать это просто решение компилятора — не из-за каких-либо ограничений допустимости. По пункту 12.8 / 31:

[…] Это исключение операций копирования / перемещения, называемых разрешением копирования, допускается в следующих обстоятельствах (которые
могут быть объединены для устранения нескольких копий):

в операторе возврата в функции с типом возврата класса, когда выражение является именем
энергонезависимый автоматический объект (отличный от параметра функции или оператора catch) с тем же cv-unqualified
type в качестве типа возврата функции, операция копирования / перемещения может быть опущена путем конструирования
автоматический объект непосредственно в возвращаемое значение функции

[…]

Однако, если вы спрашиваете, ожидая, что вы сможете сила ваш компилятор для выполнения NRVO, тогда ответ «Ты не можешь».

Это полностью по усмотрению компилятора, применять ли NRVO или нет. Вы не можете рассчитывать на это, и вы не можете рассчитывать на это не выполняется Насколько мне известно, это единственное исключение из так называемогокак будтоПравило

Это сказало, шансы получить NRVO, выполняемое, увеличиваются, поскольку Вы повысить уровень оптимизации.

4

Другие решения

Я не знаю, что вы видите в своей среде, но это работает, как и ожидалось в GCC (например, посмотреть здесь):

Нормальный:

I am in constructor
I am in constructor
I am in destructor
I am in destructor

С -fno-elide-constructors:

I am in constructor
I am in constructor
I am in copy constructor
I am in destructor
I am in destructor
I am in destructor
0

По вопросам рекламы [email protected]