Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
kelbon opened this issue Jun 19, 2023 · 3 comments
Open

Comments

@kelbon
Copy link

kelbon commented Jun 19, 2023

Вся суть проблемы с релоцированием объектов заключается в том, что компилятору неизвестно каким образом происходит мув и из кода невозможно узнать (помимо 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
Copy link

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

@kelbon
Copy link
Author

kelbon commented Jun 20, 2023

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

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

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

@kelbon
Copy link
Author

kelbon commented Jun 20, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants