WedX - журнал о программировании и компьютерных науках

Непредсказуемый выброс копии?

Согласно этой вики-странице следующий код:

#include <iostream>

struct C {
  C() = default;
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C();
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f();
}

может производить разные выходные данные в зависимости от компилятора и настроек этого компилятора.

Как я могу писать программы, если я не могу предсказать, как они будут себя вести (я действительно не могу знать, что любой данный компилятор в любой данной версии с любыми заданными настройками будет или не будет оптимизировать)? Существуют ли какие-либо общие рекомендации относительно копирования-исключения, которым я должен следовать?

29.03.2021

  • Соблюдайте правило 3/5/0 и не зависьте от присутствия/отсутствия копирования-исключения. 29.03.2021
  • Обратите внимание, что ваш пример предсказуем на С++ 17 без копий. 29.03.2021
  • В дополнение к комментарию @Jarod42: Как работает гарантированная копия? 29.03.2021
  • Можете ли вы объяснить, какие проблемы, по вашему мнению, могут возникнуть в вашей программе, если копирование выполняется или не выполняется? 29.03.2021
  • Конструкторы не должны иметь каких-либо необходимых побочных эффектов (таких как std::cout, чтобы показать, что конкретный конструктор был вызван), потому что эти побочные эффекты не гарантируются. Конструкторы особенные, и компилятору разрешено довольно агрессивно их оптимизировать. 29.03.2021
  • Полезным советом является написание кода таким образом, чтобы не имело значения, пропущена ли копия. (Когда это происходит, это очень часто является признаком проблемы дизайна.) 29.03.2021

Ответы:


1

Пишите код, который не зависит от наличия или отсутствия копирования-элизиона.

В основном это касается соблюдения правила 3/5/0.

Здесь основная цель вашего класса C — показать возможность копирования.

В обычном случае класс содержит данные и/или управляет ресурсами. Итак, тогда следует реализовать правильные конструкторы копирования/перемещения, чтобы поддерживать там инвариант, избегать двойного удаления,...

А так удаление копии это просто оптимизация.

Существуют и другие конструкции, которые могут зависеть от компилятора/сборки/запуска:

  • Порядок вычисления аргумента функции не указан. Вы должны написать код, который не зависит от порядка этой оценки.

    template <typename ... Ts> void any_order_call(Ts&&...){}
    
    std::ostream& hello() { return std::cout << "hello "; }
    std::ostream& world() { return std::cout << "world"; }
    
    void maybe_hello_world()
    {
        any_order_call(world(), hello());
    }
    

    Таким образом, вывод может быть

    hello world
    

    or

    worldhello 
    
  • sizeof(int) зависит от компилятора/архитектуры, вы не должны предполагать его размер. Для этого у вас может быть тест для этого (if (sizeof (int) == 4)) или (необязательно :()) типов фиксированного размера (std::int32_t, ...).

  • ...

29.03.2021
Новые материалы

Как создать диаграмму градиентной кисти с помощью D3.js
Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


Для любых предложений по сайту: wedx@cp9.ru