Здравствуйте, vopl, Вы писали:
V>для того чтобы увязать это с неопределенным поведением — надо проделать еще какие то шаги, одного только представленного определения не достаточно, так как в нем нет ни слова о неопределенном поведении
Вообще-то есть: "C++ program constructed according to the syntax and semantic rules". Конечно, здесь подразумевается, что мы знаем, что такое неопределенное поведение: https://timsong-cpp.github.io/cppwp/intro.defs#defns.undefined: "behavior for which this document imposes no requirements...". Два эти пункта исключают возможность порождения UB в well-formed программе. А программа, если она не well-formed, она ill-formed — также по определению. ЧТД.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, vopl, Вы писали:
V>>для того чтобы увязать это с неопределенным поведением — надо проделать еще какие то шаги, одного только представленного определения не достаточно, так как в нем нет ни слова о неопределенном поведении
R>Вообще-то есть: "C++ program constructed according to the syntax and semantic rules". Конечно, здесь подразумевается, что мы знаем, что такое неопределенное поведение: https://timsong-cpp.github.io/cppwp/intro.defs#defns.undefined: "behavior for which this document imposes no requirements...". Два эти пункта исключают возможность порождения UB в well-formed программе. А программа, если она не well-formed, она ill-formed — также по определению. ЧТД.
ну, хз, как то звучит натянуто.. Я бы на этот вопрос заходил с другой стороны, например со стороны требований к программе, ее частям и выполнению, в частности, пункт о нарушении недиагностируемых правил, из которого следует отсутствие требований к компилятору в отношении программы, в частности, к ее исполнению. Затем такое отсутствие требований можно трактовать как неопределенность поведения (по его определению).
То есть, получается:
ill-formed, no diagnostic is required — это нарушение недиагностируемого правила
нарушение недиагностируемого правила — приводик к снятию всех требований к исполнению программы
такое отсутствие требований определяется как UB
При этом, обрати внимание, просто ill-formed (без no diagnostic is required) — это следующий пункт. Там не идет речи о снятии каких либо требований, то есть, не получится выйти на какой то UB. Там постулируется просто что должен быть выброшен хотя бы один диагностирующий мессэдж и все.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, vopl, Вы писали:
V>>вот пример программы, которая well-formed и производит UB одновременно
V>>
V>>int main(int argc, char* argv[])
V>>{
V>> return argc+220;//при достаточно больших argc имеем UB вследствие переполнения инта
V>>}
V>>
R>Нет, это как раз-таки пример ill-formed программы.
никакое правило тут не нарушено. Покажи, какое правило тут нарушено? Что именно делает программу ill-formed?
R>Well-defined программа должна выглядеть как-то так: R>
Здравствуйте, vopl, Вы писали:
V>внешнее и внутреннее имена трактуются как если они ссылаются на один и тот же объект. Тогда время жизни объекта, означенного внешнем именем — трактуется как время жизни как будто бы "того же объекта". То есть, не важно как мы эту штуку назовем — один и тот же объект, или "нечто трактуемое как один и тот же объект" — все эффекты около этой штуки будут одинаковыми в обоих случаях.
Ну да, на вызывающей стороне это неотличимо, т.е., если логику buildMap вставить в конструктор некоего наследника, то будет идентичный код для такой инициализации:
const MyMap map = MyMap();
Т.е. точно так же на вызывающей стороне будет выделено место в локальной памяти под объект и адрес этой памяти будет передан аргументом в конструктор.
В этом смысле вызов конструктора неотличим от вызова фабричной ф-ии, возвращающей объект по значению (с применённым RVO).
V>Более того, эти два подхода не различимы, не возможно определить, имеем мы дело с "одним и тем же объектом" или с чемто, "с чем работать нужно как с одним и тем же"
В старых компиляторах в сниппете вызывался конструктор копирования, в более новых до C++17 применялось copy elision, теперь это всё просто называют prvalue, которое рекомендуют не материализовать без лишней необходимости.
Но семантика не поменялась — как и прежде доступ к константной переменной map возможен только после окончания инициализации объекта.
И если конструктор был без побочных эффектов вокруг this, то в наличии у нас будет только константная отсылка к объекту.
То бишь, после появления сущности-константы, уже невозожно без доп.хаков достичь обсуждаемого UB.
well-formed program
C++ program constructed (emphasis mine) according to the syntax and semantic rules
Если программа constructed according to the syntax and semantic rules , а нарушение semantic rules, или ещё что-то подходящее под определение UB, возникнет во время её execution, то это никак не отменит well-formed
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, vopl, Вы писали:
V>> никакое правило тут не нарушено. Покажи, какое правило тут нарушено? Что именно делает программу ill-formed?
R>Эта программа порождает UB. Программа, порождающая UB, не может быть well-formed по определению: 3.25, 3.65, 3.68.
Прикалуешся что ли? Масло маслянное. Ну ладно, давай по твоему, с твоей стороны зайдем.
Исходно имеем следующее определение well-formed программы:
C++ program constructed according to the syntax and semantic rules
ты заявляешь что предъявленная программа не является well-formed так как содержит UB. (напомню программу: int main(int argc, char*[]){return argc+220;}).
Для того чтобы такое следствие было истинным — следует полагать, что наличие UB — ломает according to the syntax and semantic rules.
Помним, что UB есть ни что иное как упразднение требований к поведению (программы).
в этом контексте вопрос: каким именно образом факт упразднения требований к программе (UB) приводит к нарушению каких либо синтаксических/семантических правил, на основании которых построена программа (well-formed)?
этот же вопрос, другая формулировка: какие именно синтаксические/семантические правила, в соответствии с которыми построена программа, нарушаются по факту упразднения требований к программе?
этот же вопрос, в упрощенной форме: покажи, какое именно правило нарушено в приведенной программе?
---------------------------------------------
или вообще можно с другой стороны зайти. Вот обрати внимание на пояснительную записку к UB:
undefined behavior
behavior for which this document imposes no requirements
[Note 1: Undefined behavior may be expected when
— this document omits any explicit definition of behavior or
— when a program uses an erroneous construct or
— erroneous data.
... далее поскипано неважное
в ней говорится что UB можно ожидать в случае erroneous data. Это рантайм. При этом, все те rules, в соответствии с которыми строится well-formed программа — они имеют место ДО рантайма. Но ничто более позднее (UB в рантайме по причине erroneous data) не может быть причиной более раннему (syntax and semantic rules). То есть, существуют такие UB, которые не ломают well-formed программу в ill-formed так как существуют после того как программа приобрела свойство well-formed. То есть, следующий тезис не верен: "Программа, порождающая UB, не может быть well-formed".
Если совсем строго, то реализации, ибо https://timsong-cpp.github.io/cppwp/n4868/intro.scope#1.sentence-1. А «поведение программы не определено» это более краткая/удобная форма записи «поведение реализации по отношению к программе не опеределено». Ну это так, на правах FYI
Здравствуйте, vopl, Вы писали:
V>Исходно имеем следующее определение well-formed программы: V>
C++ program constructed according to the syntax and semantic rules
V>ты заявляешь что предъявленная программа не является well-formed так как содержит UB. (напомню программу: int main(int argc, char*[]){return argc+220;}). V>Для того чтобы такое следствие было истинным — следует полагать, что наличие UB — ломает according to the syntax and semantic rules.
Конечно ломает: 3.65. "behavior for which this document imposes no requirements" не сомещается с "according to the syntax and semantic rules".
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, σ, Вы писали:
σ>Если программа constructed according to the syntax and semantic rules , а нарушение semantic rules, или ещё что-то подходящее под определение UB, возникнет во время её execution, то это никак не отменит well-formed
Если "возникнет", значит "not constructed according..." — все просто.
--
Не можешь достичь желаемого — пожелай достигнутого.
R>Если "возникнет", значит "not constructed according" — все просто.
Притащи constructed-level правило, по которому программа должна быть такой, чтобы ни для каких входных данных не могло "возникнуть" UB [во время выполнения].
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, vopl, Вы писали:
V>>Исходно имеем следующее определение well-formed программы: V>>
C++ program constructed according to the syntax and semantic rules
V>>ты заявляешь что предъявленная программа не является well-formed так как содержит UB. (напомню программу: int main(int argc, char*[]){return argc+220;}). V>>Для того чтобы такое следствие было истинным — следует полагать, что наличие UB — ломает according to the syntax and semantic rules.
R>Конечно ломает: 3.65. "behavior for which this document imposes no requirements" не сомещается с "according to the syntax and semantic rules".
ну и я говорю что ломает. Да, я делаю именно такую предпосылку. Это преамбула, читай сообщение в целом, не кусками. Там дальше будут вопросы, лучше на них ответь.
Re[106]: Когда это наконец станет defined behavior?
Здравствуйте, vopl, Вы писали:
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, но этот экземпляр в некоторой фазе исполнения программы недоступен для манипуляции через целевую константу.
Соответственно, в рассматриваемой фазе инициализации, когда еще нет доступа к объекту через константу, у этой константы не может быть вообще никакого "поведения", не то что "неопределённого", по поводу которого вы высказывали беспокойство. ))
Здравствуйте, σ, Вы писали:
R>>Если "возникнет", значит "not constructed according" — все просто.
σ>Притащи constructed-level правило, по которому программа должна быть такой, чтобы ни для каких входных данных не могло "возникнуть" UB [во время выполнения].
Правила соблюдаются только тогда, когда они соблюдаются всегда. Если правила иногда соблюдаются, а иногда нет, то это просто правила не соблюдаются. Опять все просто.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, vopl, Вы писали:
V>Там дальше будут вопросы, лучше на них ответь.
А мне не нужно "дальше", мне достаточно того, что я уже увидел. Я вообще считаю, что если человек не способен сформулировать свою мысль одним четким копактным абзацем, то в голове у него путаница. И бродить по этим лабиринтам сознания у меня мотивации ноль.
--
Не можешь достичь желаемого — пожелай достигнутого.
R>>>Если "возникнет", значит "not constructed according" — все просто.
σ>>Притащи constructed-level правило, по которому программа должна быть такой, чтобы ни для каких входных данных не могло "возникнуть" UB [во время выполнения].
R>Правила соблюдаются только тогда, когда они соблюдаются всегда. Если правила иногда соблюдаются, а иногда нет, то это просто правила не соблюдаются. Опять все просто.
Правила есть разные, и последствия от их нарушения тоже разные. Какие-то нарушения делают программу ill-formed, какие-то — не делают.
Короче. Чтобы долго воду в ступе не толочь (как ты любишь).
Я думаю, я знаю что в твоей склерозной кочерыжке с чем смешалось.
В C есть понятие strictly confirming program: > A strictly conforming program shall use only those features of the language and library specified in this International Standard. It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.
Предполагаю, ты это где-то когда-то видел, и чёт там такое запомнил про отсутствие UB для любого возможного input, чтобы программа считалась «очень хорошей», но…
Ток вот C++ — не C. В нём нет ни понятия «strictly conforming program», ни правила, что [для того, чтобы быть well-formed] в программе не должно возникать UB [во время выполнения] ни для какого возможного input.
Здравствуйте, σ, Вы писали:
σ>Правила есть разные, и последствия от их нарушения тоже разные. Какие-то нарушения делают программу ill-formed, какие-то — не делают. σ>Короче. Чтобы долго воду в ступе не толочь (я знаю, ты любишь).
Спасибо, что повеселил. Дальше читать не вижу смысла.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, vopl, Вы писали:
V>>Там дальше будут вопросы, лучше на них ответь.
R>А мне не нужно "дальше", мне достаточно того, что я уже увидел. Я вообще считаю, что если человек не способен сформулировать свою мысль одним четким копактным абзацем, то в голове у него путаница. И бродить по этим лабиринтам сознания у меня мотивации ноль.