Сообщение Re[106]: Когда это наконец станет defined behavior? от 23.08.2023 12:58
Изменено 23.08.2023 17:17 vdimas
V>так нельзя, все эти "делаем вид" должны иметь обоснование, а его нет.
Вообще-то обоснование есть и про него говорили с самого начала (рассуждения про побочные эффекты).
V>Выдавлен copy — значит его эффект стал пустым.
Но это не само в компиляторах произошло, а через многолетнюю серию обсуждений сообщества С++, где сообщество в конце всех концов пришло к консенсусу, что конструктор копирования желательно рассматривать как имеющий пустой побочный эффект, аналогично насчёт деструкторов.
Разумеется, такая интерпретация конструктора копирования ломает некоторые старые программы, в которых побочные эффекты конструкторов копирования были необходимы для корректной работы, но сообщество С++ пошло на этот шаг, принеся "свободу делать что хочу" в жертву оптимальности при всё еще достаточной выразительности.
В общем, это был достаточно болезненный шаг и одна из причин, почему фиксация стандарта С++11 настолько затянулась (более 5-ти лет! изначально тот стандарт должен был выйти в нулевые, его так и называли предварительно — C++0x)
Из предисловия к "Язык программирования С++", 4 ред.:
С годами использование C++ сильно изменилось, как и сам язык. С точки зрения программиста, большинство изменений были улучшениями. Текущий стандарт ISO C++ (ISO/IEC 14882:2011, обычно называемый C++11) — это просто гораздо лучший инструмент для написания качественного программного обеспечения, чем предыдущие версии. Насколько это лучший инструмент? Какие стили и приемы программирования поддерживает современный C++? Какие функции языка и стандартной библиотеки поддерживают эти методы? Каковы основные строительные блоки элегантного, правильного, поддерживаемого и эффективного кода C++? Вот основные вопросы, на которые отвечает эта книга. Многие ответы отличаются от тех, которые вы могли бы найти в C++ 1985, 1995 или 2005 года выпуска: прогресс происходит.
От себя добавлю, что в С++ намного больше здравого смысла, чем может показаться при поверхностном взгляде.
Для любого решения, принятого в языке, есть тонны обснований — многолетних обсуждений + миллионы строк наработанной практики.
(например, конструкторы перемещения эмулировались задолго до появления в стандарте, у нас в конторе аналоги exception_ptr были для стандарта С++03, для него же promise/future и т.д. и т.п.)
V>Нет оснований полагать, что copy elision относится только к части copy. Он относится ко всему copy целиком, со всеми его эффектами, включая связность с lifetime
Разумеется.
В этом и состоит консенсус, что, согласно синтаксиса и семантики программы copy constructor присутствует и вызывается (я же предлагал попытаться провернуть тот же трюк при недоступном конструкторе копирования), но компилятору разрешается опускать конструкторы копирования/перемещения, считая их как если бы они не содержали побочных эффектов — в этом случае гарантируется соблюдение семантики исходника в рантайме.
Если же ты в конструкторы копирования вставишь, допустим, логгирование (побочный эффект, а так же вставить логгирование в деструктор), то сохранение семантики программы уже НЕ гарантируется.
В общем, это был сознательный шаг.
Но одновременно с этим были выработаны определённые шаблоны проектирования для объектов, имеющих подобные побочные эффекты при конструировании/разрушении:
— у таких объектов запрещены конструкторы копирования/перемещения/operator= (примечание: такие конструкторы, конечно, могут существовать в прикладных целях, но их стоит объявлять как explicit и/или приватными/защищёнными);
— в качестве бонуса зато можно пользоваться адресом объекта как его identity из ООП-парадигмы (т.е. защитив объект от "случайного" перемещения или копирования).
=================================
ИМХО, бесполезно изучать С++ через стандарт.
Стандарт может и должен использоваться сугубо как справочник, но он не подскажет приёмы/техники/шаблоны проектирования, ради которых стандарт именно таков, какой он есть.
Т.е. стандарт — это как готовый ответ без постановки задачи, бгг.
- Петька, приборы!
— 42!
— Что "42"?
— А что "приборы"?
Разумеется, в пределе аналитических скилов стандарт может "подсказать" исходную постановку задачи, если знать стандарт наизусть и держать его в памяти целиком, но это не самый эффективный путь, ес-но. ))
Именно поэтому я неоднократно призывал плясать не от определения UB, а от сценариев, где оно может себя проявить.
Иначе возникают спекуляции, как у вас, где вы запросто рассуждаете о том, что константный объект уже определён, хотя он нифига не определён. ))
Определён экземпляр объекта через трюк RVO — OK, но этот экземпляр в некоторой фазе исполнения программы недоступен для манипуляции через целевую константу.
Соответственно, в рассматриваемой фазе инициализации, когда еще нет доступа к объекту через константу, у этой константы не может быть вообще никакого "поведения", не то что "неопределённого", по поводу которого вы высказывали беспокойство. ))
V>так нельзя, все эти "делаем вид" должны иметь обоснование, а его нет.
Вообще-то обоснование есть и про него говорили с самого начала (рассуждения про побочные эффекты).
V>Выдавлен copy — значит его эффект стал пустым.
Но это не само в компиляторах произошло, а через многолетнюю серию обсуждений сообщества С++, где сообщество в конце всех концов пришло к консенсусу, что конструктор копирования желательно рассматривать как имеющий пустой побочный эффект, аналогично насчёт деструкторов.
Разумеется, такая интерпретация конструктора копирования ломает некоторые старые программы, в которых побочные эффекты конструкторов копирования были необходимы для корректной работы, но сообщество С++ пошло на этот шаг, принеся "свободу делать что хочу" в жертву оптимальности при всё еще достаточной выразительности.
В общем, это был достаточно болезненный шаг и одна из причин, почему фиксация стандарта С++11 настолько затянулась (более 5-ти лет! изначально тот стандарт должен был выйти в нулевые, его так и называли предварительно — C++0x)
Из предисловия к "Язык программирования С++", 4 ред.:
С годами использование C++ сильно изменилось, как и сам язык. С точки зрения программиста, большинство изменений были улучшениями. Текущий стандарт ISO C++ (ISO/IEC 14882:2011, обычно называемый C++11) — это просто гораздо лучший инструмент для написания качественного программного обеспечения, чем предыдущие версии. Насколько это лучший инструмент? Какие стили и приемы программирования поддерживает современный C++? Какие функции языка и стандартной библиотеки поддерживают эти методы? Каковы основные строительные блоки элегантного, правильного, поддерживаемого и эффективного кода C++? Вот основные вопросы, на которые отвечает эта книга. Многие ответы отличаются от тех, которые вы могли бы найти в C++ 1985, 1995 или 2005 года выпуска: прогресс происходит.
От себя добавлю, что в С++ намного больше здравого смысла, чем может показаться при поверхностном взгляде.
Для любого решения, принятого в языке, есть тонны обснований — многолетних обсуждений + миллионы строк наработанной практики.
(например, конструкторы перемещения эмулировались задолго до появления в стандарте, у нас в конторе аналоги exception_ptr были для стандарта С++03, для него же promise/future и т.д. и т.п.)
V>Нет оснований полагать, что copy elision относится только к части copy. Он относится ко всему copy целиком, со всеми его эффектами, включая связность с lifetime
Разумеется.
В этом и состоит консенсус, что, согласно синтаксиса и семантики программы, copy constructor присутствует и вызывается (я же предлагал попытаться провернуть тот же трюк при недоступном конструкторе копирования), но компилятору разрешается опускать конструкторы копирования/перемещения, считая их как если бы они не содержали побочных эффектов — в этом случае гарантируется соблюдение семантики исходника в рантайме.
Если же ты в конструкторы копирования вставишь, допустим, логгирование (побочный эффект, а так же вставить логгирование в деструктор), то сохранение семантики программы уже НЕ гарантируется.
В общем, это был сознательный шаг.
Но одновременно с этим были выработаны определённые шаблоны проектирования для объектов, имеющих подобные побочные эффекты при конструировании/разрушении:
— у таких объектов запрещены конструкторы копирования/перемещения/operator= (примечание: такие конструкторы, конечно, могут существовать в прикладных целях, но их стоит объявлять как explicit и/или приватными/защищёнными);
— в качестве бонуса зато можно пользоваться адресом объекта как его identity из ООП-парадигмы (т.е. защитив объект от "случайного" перемещения или копирования).
=================================
ИМХО, бесполезно изучать С++ через стандарт.
Стандарт может и должен использоваться сугубо как справочник, но он не подскажет приёмы/техники/шаблоны проектирования, ради которых стандарт именно таков, какой он есть.
Т.е. стандарт — это как готовый ответ без постановки задачи, бгг.
- Петька, приборы!
— 42!
— Что "42"?
— А что "приборы"?
Разумеется, в пределе аналитических скилов стандарт может "подсказать" исходную постановку задачи, если знать стандарт наизусть и держать его в памяти целиком, но это не самый эффективный путь, ес-но. ))
Именно поэтому я неоднократно призывал плясать не от определения UB, а от сценариев, где оно может себя проявить.
Иначе возникают спекуляции, как у вас, где вы запросто рассуждаете о том, что константный объект уже определён, хотя он нифига не определён. ))
Определён экземпляр объекта через трюк RVO — OK, но этот экземпляр в некоторой фазе исполнения программы недоступен для манипуляции через целевую константу.
Соответственно, в рассматриваемой фазе инициализации, когда еще нет доступа к объекту через константу, у этой константы не может быть вообще никакого "поведения", не то что "неопределённого", по поводу которого вы высказывали беспокойство. ))