Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 07:32
Оценка: 6 (1)
Всем привет!

Вопрос несколько философский. Правомерно ли делать какие-либо допущения о состоянии объета, в самом общем случае, после того, как его содержимое было перемещено? Разумеется, состояние объекта должно позволять разрушить этот объект, это сомнению не прдвергается. Но достаточно ли этого? Ведь помимо физического тела у объекта есть еще и логическое состояние — его душа, так сказать. Так вот как быть с ней — нужно ли заботиться о том, чтобы после перемещения объект оставался в целостном состоянии с точки зрения логики программы — на тот случай, если кому-то захочется продолжать пользоваться объектом после его перемещения?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: Есть ли жизнь после перемещения?
От: TimurSPB Интернет  
Дата: 20.11.18 07:49
Оценка:
R>Вопрос несколько философский. Правомерно ли делать какие-либо допущения о состоянии объета, в самом общем случае, после того, как его содержимое было перемещено? Разумеется, состояние объекта должно позволять разрушить этот объект, это сомнению не прдвергается. Но достаточно ли этого? Ведь помимо физического тела у объекта есть еще и логическое состояние — его душа, так сказать. Так вот как быть с ней — нужно ли заботиться о том, чтобы после перемещения объект оставался в целостном состоянии с точки зрения логики программы — на тот случай, если кому-то захочется продолжать пользоваться объектом после его перемещения?
В писании сказано:

Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

Как я понимаю, в общем случае нужно заботиться о целостности объекта после его перемещения.
Make flame.politics Great Again!
Re[2]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 07:59
Оценка:
Здравствуйте, TimurSPB, Вы писали:

TSP>В писании сказано:

TSP>

TSP>Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

TSP>Как я понимаю, в общем случае нужно заботиться о целостности объекта после его перемещения.

Ну так вот вопрос о понимании этой самой целостности. Одно дело, целостность для того, чтобы похоронить объект и совсем другое — целостность для того, чтобы продолжать им пользоваться.

Этот вопрос можно сформулировать и по-другому: стоит ли требовать от разработчиков, в самом общем случае, документирования состояния объектов после перемещениея? Или исплользование объектов после перемещения — это зло, с которым нужно бороться? Или могут быть варианты?

P.S. Понятно, что из любого правила могут быть исключения. Но хотелось бы понимать, все-таки, каково же само правило.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 20.11.2018 8:06 rg45 . Предыдущая версия .
Re: Есть ли жизнь после перемещения?
От: Пирожочек  
Дата: 20.11.18 08:09
Оценка: 11 (2) +1
Здравствуйте, rg45, Вы писали:

R>Всем привет!

приветик

R>Так вот как быть с ней — нужно ли заботиться о том, чтобы после перемещения объект оставался в целостном состоянии с точки зрения логики программы — на тот случай, если кому-то захочется продолжать пользоваться объектом после его перемещения?

после перемещения объект должен поддерживать две операции — деструкцию и присваивание. Инвариант класса он поддерживать не обязан.
Re[3]: Есть ли жизнь после перемещения?
От: TimurSPB Интернет  
Дата: 20.11.18 08:09
Оценка:
R>Этот вопрос можно сформулировать и по-другому: стоит ли требовать от разработчиков, в самом общем случае, документирования состояния объектов после перемещениея? Или исплользование объектов после перемещения — это зло, с которым нужно бороться? Или могут быть варианты?
Если требуется использование объектов после перемещения и процесс разработки требует документирования всего, то да нужно. А куда деваться? В таком случае лучше всего иметь тест на валидность объекта после перемещения. И без теста пулл-реквест не апрувить.
Зло это или нет, можно определить в контексте конкретного кода. Должна быть внятная мотивация для использования перемещённых объектов, например производительность или экономия памяти. ИМХО, если можно обойтись без этого, то ну его нафиг.
Make flame.politics Great Again!
Re: Есть ли жизнь после перемещения?
От: Videoman Россия https://hts.tv/
Дата: 20.11.18 08:26
Оценка: 25 (2)
Здравствуйте, rg45:

Вопрос действительно философский. По мне, как минимум после перемещения должны работать еще две операции: swap (если есть) и присваивание (operator=).
В процессе опыта реализации перемещения разных объектов, решил что оставлять объект в валидном состоянии, в общем случае, может быть дороговато (зависит от объекта конечно), да и начинают вылезать нежелательные практики от которых, вроде как, хотелось уйти. Постараюсь объяснить что я имею ввиду:
Если строго соблюдать RAII, то в классах многих объектов отсутствуют конструкторы по умолчанию. В С++ это удобно делать если объект в "дефолтном" состоянии не имеет смысла и не может делать ничего полезного. Также такой объект не может быть в не инициализированном состоянии и не нужны внутренние проверки на валидность состояния при вызове публичных методов (максимум ассерты). Все хорошо и концепция жива пока мы не сделаем перемещение объекта. Если после перемещения продолжать работу с таким объектом, то тут же "вылезает" новое "дефолтое" состояние, такое же как в случае двойной инициализацией все преимущества RAII идут лесом.
Re: Есть ли жизнь после перемещения?
От: andyp  
Дата: 20.11.18 09:06
Оценка: :))
Здравствуйте, rg45, Вы писали:

R>Вопрос несколько философский. Правомерно ли делать какие-либо допущения о состоянии объета, в самом общем случае, после того, как его содержимое было перемещено?


Вот есть у тебя плюшевый медведь в коробке. Ты его в другую коробку переложил. Что можно сделать с коробкой? Выкинуть коробку(почему-то это будет деструктор медведя) или сунуть тем или иным способом в нее другого медведя (assignment, move опять же для медведя ). Проблема в том, что move семантика в C++ до конца не допилена имхо. В рамках системы типов ты не можешь формально отличить медведя от пустой коробки для него и все вопросы крутятся вокруг того, считать ли пустую коробку тоже медведем.
Re: Есть ли жизнь после перемещения?
От: kov_serg Россия  
Дата: 20.11.18 09:56
Оценка: +1
Здравствуйте, rg45, Вы писали:

R>Всем привет!


R>Вопрос несколько философский. Правомерно ли делать какие-либо допущения о состоянии объета, в самом общем случае, после того, как его содержимое было перемещено? Разумеется, состояние объекта должно позволять разрушить этот объект, это сомнению не прдвергается. Но достаточно ли этого? Ведь помимо физического тела у объекта есть еще и логическое состояние — его душа, так сказать. Так вот как быть с ней — нужно ли заботиться о том, чтобы после перемещения объект оставался в целостном состоянии с точки зрения логики программы — на тот случай, если кому-то захочется продолжать пользоваться объектом после его перемещения?


У меня другой философский вопрос: Стоило вводить move семантику вообще что бы потом иметь дополнительные проблемы или можно было обойтись дополнительным стеком для каждого потока не приязанного с стеку вызовов?
Re: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 20.11.18 10:32
Оценка:
Здравствуйте, rg45, Вы писали:

R>нужно ли заботиться о том, чтобы после перемещения объект оставался в целостном состоянии с точки зрения логики программы — на тот случай, если кому-то захочется продолжать пользоваться объектом после его перемещения?



1) IMHO, вопрос хороший. С ещё одной стороны показывает насколько убога концепция мув-семантики.

2) Опять же, IMHO, нужно идти от того, какие сценарии, с использованием оставшегося после перемещения объекта, мы считаем валидными.
В простых сценариях, вроде отдали/передали временное значение, или то, что больше не хотим использовать, ясно, что использование объекта, данные из которого перемещены, само по себе подозрительно, но, к сожалению, есть сценарии, вроде вставки/удаления элемента в середине массива, например.

Есть ли ещё какие-то вменяемые сценарии, в которых постперемещённые объекты как-то используются?


3) Если все нужды сводятся к (2), то я бы вообще от мув-семантики отказался, во всяких передачах/заменах использовал бы RVO/NRVO, а для перемещений из буфера в буфер массивов элементов завёл бы специальную шаблонную функцию, которую бы пользователи STL могли бы для своих типов перекрывать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Есть ли жизнь после перемещения?
От: Videoman Россия https://hts.tv/
Дата: 20.11.18 13:25
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>У меня другой философский вопрос: Стоило вводить move семантику вообще что бы потом иметь дополнительные проблемы или можно было обойтись дополнительным стеком для каждого потока не приязанного с стеку вызовов?


А можно поподробней, что имеется ввиду? Это другая модель абстрактной машины что ли? Так это уже не С вовсе будет, не?
Re[2]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 14:10
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>У меня другой философский вопрос: Стоило вводить move семантику вообще что бы потом иметь дополнительные проблемы или можно было обойтись дополнительным стеком для каждого потока не приязанного с стеку вызовов?


А что такое "move семантика вообще"? Это:

1) Новый тип ссылок, позволяющий, обработать временный объект по-другому, чем не временный;
2) Операция move, позволяющая обработать не временный объект, как временный.

И если возможность номер два, при определенной степени разгильдяйства, способна приводить к проблемам, это разве повод, чтобы отказываться от возможности номер один?

А с возможностью форвардинга как быть? От нее тоже отказываемся?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 14:21
Оценка: +1
Здравствуйте, andyp, Вы писали:

A>Вот есть у тебя плюшевый медведь в коробке. Ты его в другую коробку переложил. Что можно сделать с коробкой? Выкинуть коробку(почему-то это будет деструктор медведя) или сунуть тем или иным способом в нее другого медведя (assignment, move опять же для медведя ). Проблема в том, что move семантика в C++ до конца не допилена имхо. В рамках системы типов ты не можешь формально отличить медведя от пустой коробки для него и все вопросы крутятся вокруг того, считать ли пустую коробку тоже медведем.


Здесь проблема скорее в выбранной аналогии, чем собственно в move семантике. Замени "Коробка и медведь" на "медведь и опилки" и степень удивленности резко снизится
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Есть ли жизнь после перемещения?
От: B0FEE664  
Дата: 20.11.18 14:23
Оценка: +2
Здравствуйте, kov_serg, Вы писали:

_>У меня другой философский вопрос: Стоило вводить move семантику вообще что бы потом иметь дополнительные проблемы или можно было обойтись дополнительным стеком для каждого потока не приязанного с стеку вызовов?


У меня другой философский вопрос: если вам не нравится move семантика, то зачем ею пользоваться? Не пользуйтесь и вы не заметите изменений почти никогда.
И каждый день — без права на ошибку...
Re[2]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 14:23
Оценка:
Здравствуйте, Erop, Вы писали:

E>1) IMHO, вопрос хороший. С ещё одной стороны показывает насколько убога концепция мув-семантики.


Не могу согласиться, при всем уважении. ИМХО, это скорее показывает какой-то неудачный опыт применения.

E>2) Опять же, IMHO, нужно идти от того, какие сценарии, с использованием оставшегося после перемещения объекта, мы считаем валидными.


Так это я об этом спрашиваю, вообще-то
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Есть ли жизнь после перемещения?
От: ViTech  
Дата: 20.11.18 14:29
Оценка: 17 (2) +1
Здравствуйте, TimurSPB, Вы писали:

TSP>В писании сказано:

TSP>

TSP>Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

TSP>Как я понимаю, в общем случае нужно заботиться о целостности объекта после его перемещения.

Считаю, что нужно ещё начало выделить:

Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.


И понимаю так, что в писании valid but unspecified state относится к objects of types defined in the C++ standard library, а не ко всем типам, написанным на C++ вообще. Т.е. в своих классах можно и другого поведения придерживаться. Но я тоже сторонник того, что перемещённый объект можно или удалить, или присвоить ему новое значение. И не пытаться использовать его, пусть он хоть и в valid but unspecified state. Т.е. души/сущности у перемещённого объекта нет, остаётся только оболочка .
Пока сам не сделаешь...
Re[3]: Есть ли жизнь после перемещения?
От: andyp  
Дата: 20.11.18 14:40
Оценка: 5 (1)
Здравствуйте, rg45, Вы писали:

R>Здесь проблема скорее в выбранной аналогии, чем собственно в move семантике. Замени "Коробка и медведь" на "медведь и опилки" и степень удивленности резко снизится


Ну вот смотри, у Степанова в книжке я первый первый раз подход к снарядам на эту тему встретил. (На самом деле он там про эффективный swap пишет). Так вот, он там вводит понятие UnderlyingType<T>:

The implementation of the underlying type for an original type T is
straightforward and could be automated. U = UnderlyingType(T) always has the same layout as
the header of T. The copy constructor and assignment for U just copy the bits; they
do not construct a copy of the remote parts of T
.


swap в его исполнении выглядит как

template<typename T> 
requires(Regular(T)) 
void swap(T& x, T& y) 
{ 
    UnderlyingType(T) tmp = underlying_ref (x) ; 
    underlying_ref (x) = underlying_ref (y) ; 
    underlying_ref (y) = tmp; 
}


Т.е. он уже начал подумывать как различать мишку, коробку и мишку в коробке. Имхо, в стране розовых пони, если ты смувил из объекта, его тип должен автоматически переключаться на Вох<T> и не давать тебе с таким объектом шалить. Сама концепция такой коробки тоже достаточно полезна имхо.
Re: Есть ли жизнь после перемещения?
От: B0FEE664  
Дата: 20.11.18 14:46
Оценка:
Здравствуйте, rg45, Вы писали:

R>Вопрос несколько философский. Правомерно ли делать какие-либо допущения о состоянии объета, в самом общем случае, после того, как его содержимое было перемещено?


Я придерживаюсь той философии, что после перемещения объект можно только разрушить вызвав деструктор (что, как правило, происходит автоматически), а больше с перемещённым объектом ничего делать не следует.
И каждый день — без права на ошибку...
Re[4]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 14:47
Оценка:
Здравствуйте, andyp, Вы писали:

A>Ну вот смотри, у Степанова в книжке я первый первый раз подход к снарядам на эту тему встретил. (На самом деле он там про эффективный swap пишет). Так вот, он там вводит понятие UnderlyingType<T>:


A>Т.е. он уже начал подумывать как различать мишку, коробку и мишку в коробке. Имхо, в стране розовых пони, если ты смувил из объекта, его тип должен автоматически переключаться на Вох<T> и не давать тебе с таким объектом шалить. Сама концепция такой коробки тоже достаточно полезна имхо.


Степанов — это Степанов, мишка — это мишка, а коробка — это коробка. Я полагаю, что вещи лучше, все-таки, называть своими именами и не смешивать одно с другим.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 14:54
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Я придерживаюсь той философии, что после перемещения объект можно только разрушить вызвав деструктор (что, как правило, происходит автоматически), а больше с перемещённым объектом ничего делать не следует.


Я, в общем-то придеживаюсь близких взлядов, но формулирую их чуть по-другому: "не следует применять операцию move к объекту, который предполагается еще использовать". Вроде бы, одно и то же, но звучит более логично, имхо.

А как насчет операции присваивания (или reset какой-нибудь)? Я не вижу причин, фигурально выражаясь, запрещать возможность вдохнуть в объект новую жизнь.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: Есть ли жизнь после перемещения?
От: andyp  
Дата: 20.11.18 14:55
Оценка:
Здравствуйте, rg45, Вы писали:

R>Степанов — это Степанов, мишка — это мишка, а коробка — это коробка. Я полагаю, что вещи лучше, все-таки, называть своими именами и не смешивать одно с другим.


Извини, я не имел возможности всё это серьезно продумать, поэтому могло выйти невнятно. Надеюсь, всё же, моя позиция по вызовы деструкторов объектов, которые уже переместили, достаточно ясна — не смысла это делать для того, чего уже там нет. И уж тем более нет смысла в деструкторе объекта отслеживать, осталась от него только оболочка или нет.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.