cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Решение проблемы релоцирования объектов #564

Open kelbon opened 1 year ago

kelbon commented 1 year ago

Вся суть проблемы с релоцированием объектов заключается в том, что компилятору неизвестно каким образом происходит мув и из кода невозможно узнать (помимо trivial мува) каково поведение типа.

Но если посмотреть на проблему шире, оказывается, что валидных стратегий реализации мув конструктора всего 4:

  1. memcpy (trivial move)
  2. exchange с дефолтным состоянием
  3. self reference сценарий
  4. у объекта вовсе нет мува, а есть только копирование(С++03 объект) ну или тип вообще не movable, но очевидно его и релоцировать нельзя Так вот, сейчас в С++ представлен только первый тип как = default и трейт is_trivially_move_constructible,

Я предлагаю

добавить сценарий 2 как стратегию поведения на муве и трейты для этого, например

Type(Type&&) = default; // то что сейчас, мув конструктор у всех филдов/базовых классов

Type(Type&&) = swap; // дефолтное конструирование + вызов swap через adl для всех филдов и базовых классов

То же самое можно сделать с оператором Type& operator=(Type&&) = swap; // типичная реализация мув оператора

и добавить трейт is_not_self_reference который будет давать true если у типа и рекурсивно у всех типов за ним нет нетривиальных мувов. Т.к. фактически нет никакого смысла делать нетривиальный мув при таких условиях

Это

Более того, практически все дефолтные конструкторы и деструкторы можно сделать constexpr, даже у std::any такой конструктор. компилятор может "выдумать" объект и дефолтно его сконструировать, а потом разрушить и на компиляции узнать, что деструктор был noop.

Для этого я предлагаю ещё один трейт is_trivially_destructible_after_move

KindDragon commented 1 year ago

std::is_trivially_relocatable помоему направлен на решение тойже проблемы другим путем https://github.com/cplusplus/papers/issues/43

kelbon commented 1 year ago

std::is_trivially_relocatable помоему направлен на решение тойже проблемы другим путем cplusplus/papers#43

я прекрасно знаю об этом и многих других пропозалах, их проблема в том, что они не помогают компилятору ничего вывести и не уменьшают количество нужного кода, а лишь увеличивают. Например, нужно будет аттрибутом или ещё как то помечать типы тривиальные для релоцирования, к тому же нет ничего что уже сейчас бы не было доступно, т.е. прямо сейчас вы можете сделать using relocatable = int; внутри типа, потом в алгоритмах это проверять. Это будет надёжнее аттрибута. Короче говоря усложнение языка без профитов

Моё предложение делает эту работу за программиста и позволяет старому коду стать лучше, иногда с минимальными изменениями типа = swap, позволит компилятору вовсе не генерировать мув конструкторы и т.д.

kelbon commented 1 year ago

И если говорить про трейт is_trviially_destructible_after_move я считаю это первый шаг к тому чтобы статически доказывать семантические утверждения про типы, то чего так хотел Страуструп.