Вопрос

Пожалуйста, рассмотрите следующий код,

struct foo
{
    foo()
    {
        std::cout << "Constructing!" << std::endl;
    }

    foo(const foo& f)
    {
        std::cout << "Copy constructing!" << std::endl;
    }

    ~foo()
    {
        std::cout << "Destructing.." << std::endl;
    }
};

foo get()
{
    foo f;
    return f;
}

int main()
{
    const foo& f = get();
    std::cout << "before return" << std::endl;
    return 0;
}

Выход на MSVC.

Constructing!
Copy constructing!
Destructing..
before return
Destructing..

Выход GCC.

Constructing!
before return
Destructing..

Результат, который поставляется на MSVC, выглядит неверным.

Вопросы

  1. AFAIK, GCC производит правильный результат здесь. Почему MSVC дает разные результаты и почему он делает Copy Construction?
  2. const foo& f = get() а также const foo f = get() производит такой же вывод из-за оптимизации возврата стоимости. В этом случае, какой способ написания должен быть предпочтительным?

Есть предположения..

Это было полезно?

Решение

Ваша сборка MSVC не имеет оптимизации. Включите их, вы получите идентичный вывод для обоих.

GCC просто выполняет, по умолчанию, RVO на вашем временном. Это в основном делает:

const foo& f = foo();

MSVC нет. Это делает foo В функции, копируя его на внешнюю функцию (ERGO COVER COVELOR CONSTOROR), разрушая внутреннее foo, Затем связывает ссылку.

Оба выхода являются правильными. RVO - это один экземпляр, где стандарт явно позволяет наблюдать наблюдаемое поведение программы для изменения.

Другие советы

Вы видите Оптимизация возврата стоимости, что является одним видом Скопировать ELINISE.. Отказ Обе программы верны; Компилятор специально дан возможность устранения временного, которые служат только для перемещения данных из одного постоянного объекта к другому.

Функция GET () построит локальное (построение печати!) И возвращает объект foo по значению. Возвращенные возвращенные объекта FOO должны быть созданы и выполнены с помощью Copy Construction (Print Copy Constring!). Обратите внимание, что это значение объекта, присвоенной Const Foo & F в основном.

Прежде чем это назначение происходит, хотя функция должна возвращаться из GET () и локальных переменных (т.е. foo f; в get ()) должна быть уничтожена. (Печать 1-го разрушения ..) Оттуда завершается программа (т.е. возврат от Main), затем объект, возвращаемый GET () и назначен на «F», разрушен. (Печать 2-го разрушения ...)

Причина, по которой вы видите разные вывода для двух компиляторов, заключается в том, что GCC оптимизирует возвращаемое значение для получения () и просто заменяет const foo &f = get() к const foo &f = foo;

1) Это происходит из-за разной стратегии оптимизации. Поскольку у вас нет оператора =, MSVC может реструктурировать код для чего-то вроде const foo & f (get ()), поэтому выполняющий копию настроек. 2) Зависит от того, что вы хотите достичь:

const foo& f = get();
f = get(); // Incorrect, const references cannot be reassigned.
const foo g = get();
g = get(); // Correct.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top