Здравствуйте, σ, Вы писали:
σ>>>Когда объект один в обоих местах, то он либо константный и там и там, либо не там и не там. Если он константный, то его модифицировать его в функции это UB. А если неконстантный, то его можно модифицировать вне функции, это не UB.
BFE>>(тихо хихикая) Т.е. согласно вашей логике, исходный пример BFE>>
BFE>>- это UB, если NRVO ?
σ>Может да. Может нет. Может на это сложно/невозможно ответить. σ>Я об этом спросил у форумчан, но в ответ получил тонну истерики, и ни одной попытки описания поведения со ссылками на стандарт. ¯\_(ツ)_/¯
Последнее время ссылаться на стандарт становится дурным тоном, так как комитет занят безумной попыткой описать формальное поведение на естественном английском языке. Эта задача не выполнима, так как под каждое словесное описание придётся дополнительно писать толкование написанных слов. Дошло до того, что стандарт невозможно понять без proposal'ов. Это состояние усугубляется некоторыми деятелями, которые стремятся получить формально корректное описание вопреки заложенным намерениям. Собственно, см. subj.
BFE>>А ничего, что возвращаемый функцией buildMap() тип отличается от типа объекта someDictionary? Не смущает? σ>Сделай глубойкий вдох, убедись, что отличаешь переменные от объектов (и, следовательно, тип переменной от типа объекта), и попробуй сказать, какой же тип у объекта в случае NRVO, т.е. когда переменные result и someDictionary обозначают один и тот же объект.
О! Да неужели?! Вы, наконец-то, начали отличать тип переменной от типа объекта и тип объекта от самого объекта?! Ура!
Смотрите, функция buildMap() возвращает объект типа std::map<int, int>, а потом в выражении const std::map<int, int> someDictionary = buildMap(); этим ( полученным из функции buildMap() ) объектом инициализируется переменная someDictionary. NRVO — это про то, что возвращает функция, а не про инициализацию константного объекта обозначенного именем someDictionary. То, что потом случается сopy elision к самой функции отношения уже не имеет.
Если в стандарте описано что-то другое, то этот стандарт надо подправить, а не поведение менять.
И каждый день — без права на ошибку...
Re[100]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
S>>Проссыте, но тема слишком большая чтобы искать оригинал. В чем принципиальные отличия от исходного оригинала или от упрощенного варианта с struct S? По сравнению с упрощенным я принципиальных отличий не вижу. Покажите пальцем, плиз.
σ>Я предложил вместо кода из https://rsdn.org/forum/cpp/8581729.1
Вот хоть убейте, но никаких существенных отличий между ними двумя не вижу. Так что нет причин откатываться вот прям к исходному оригиналу.
S>>>>Если при этом есть какие-то нарушения стандарта, то хотелось бы об этом услышать.
σ>>>В свою очередь, хотелось бы увидеть описание поведения (с т.з. стандарта, естественно)
S>>Напоминает зацикливание. Следовательно таким путем никуда не придем.
σ>По-моему, никто (кроме меня) ещё не пытался даже начать описывать, так что зацикливаться некуда.
Когда вас просят ответить предметно вы просите привести цитату. Снова и снова. Вот и зацикливание.
Re[98]: Когда это наконец станет defined behavior?
S>Приведите пример когда объект создается без выделения памяти под него и без присваивания ему значения (если мы говорим об объектах, а не о банальных int-ах). Этого будет достаточно.
S>А то у вас есть привычка на прямые вопросы и просьбы отвечать избирательно.
Я вообще не понимаю с чего ты докопался до меня этим требованием тебе что-то показать про объекты без памяти. Что тебе показалось что я утверждал? Что ты пытаешься оспорить? Сформулируй внятно, плез.
S>если мы говорим об объектах, а не о банальных int-ах
Про это я вообще не понял. Объект типа int — не объект?
Re[100]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
S>>Так что UB будет только если мы попробуем поменять константный объект уже после завершения функции из которого мы объект вернули. Но не до того как. σ>И каким же образом объект вдруг поменяет свою константность?
Только не объект, а переменная.
Переменная и не меняет свою константность — это твои смешные фантазии.
Переменная как identity объекта становится доступной для использования только после инициализации объекта, поэтому "менять константность" не требуется.
S>>Ну и я был бы признателен, если бы вы объяснили несведующему, как так получается, что объект константный, но во время работы его конструктора у нас this указывает отнюдь не на константный объект σ>this во время конструкции константного объекта указаывает, внезапно, на константный объект.
this указывает на неконстантный объект, в чём ты можешь легко убедиться.
И в чём твоя проблема?
Гугл-переводчик сломался?
RV-оптимизация происходит, на секундочку, над конструктором копирования.
Или это тебе не конструктор уже? ))
Re[101]: Когда это наконец станет defined behavior?
, надо описать поведение первого кода. Только не "эмпирически".
А не про то, что засовывание const std::map<int, int> someDictionary = buildMap(); внутрь функции что-то принципиально поменяет
S>Когда вас просят ответить предметно вы просите привести цитату. Снова и снова. Вот и зацикливание.
Я предметно дохрена написал. В ответ получил про эмпирический опыт ощущения объектов, которые софистика, которая есть только на уровне стандарта.
Re[102]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
S> В ответ получил про эмпирический опыт ощущения объектов, которые софистика, которая есть только на уровне стандарта.
Кто тебе виноват, что ты не знаешь, что такое УБ на практике и как оно должно проявляться? Поэтому вместо нормального разговора тыкаешь в буквы, которые ты не понимаешь?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[94]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
σ>Сделай глубойкий вдох, убедись, что отличаешь переменные от объектов (и, следовательно, тип переменной от типа объекта)
Опять хамишь, хотя сам же косячишь в рассуждениях.
Потом обижаешься на отлуп. ))
Если рассуждать "полностью корректно", то можно говорить только о типах данных, о данных соотв. типов и о переменных, где хранятся данные соотв. типов.
В общем, если хочешь получить технически грамотный ответ — спрашивай технически грамотно.
Если спрашиваешь "своими словами" аки брат Нибэнимеда — то тебе рукой и показывают, согласно демонстрируемого тобой уровня восприятия инфы.
Re[95]: Когда это наконец станет defined behavior?
BFE>Последнее время ссылаться на стандарт становится дурным тоном, так как комитет занят безумной попыткой описать формальное поведение на естественном английском языке. Эта задача не выполнима, так как под каждое словесное описание придётся дополнительно писать толкование написанных слов. Дошло до того, что стандарт невозможно понять без proposal'ов. Это состояние усугубляется некоторыми деятелями, которые стремятся получить формально корректное описание вопреки заложенным намерениям. Собственно, см. subj.
Nice copium.
BFE>>>А ничего, что возвращаемый функцией buildMap() тип отличается от типа объекта someDictionary? Не смущает? σ>>Сделай глубойкий вдох, убедись, что отличаешь переменные от объектов (и, следовательно, тип переменной от типа объекта), и попробуй сказать, какой же тип у объекта в случае NRVO, т.е. когда переменные result и someDictionary обозначают один и тот же объект.
BFE>О! Да неужели?! Вы, наконец-то, начали отличать тип переменной от типа объекта и тип объекта от самого объекта?! Ура!
Где ты видел, что я не отличаю?
BFE>Смотрите, функция buildMap() возвращает объект типа std::map<int, int>, а потом в выражении const std::map<int, int> someDictionary = buildMap(); этим ( полученным из функции buildMap() ) объектом инициализируется переменная someDictionary.
Не думаю, что это описание подходит для C++17 и выше. И ты отвечаешь не на то, про что я спросил. Видимо, тоже не понял, про что вопрос.
BFE>NRVO — это про то, что возвращает функция, а не про инициализацию константного объекта обозначенного именем someDictionary. То, что потом случается сopy elision к самой функции отношения уже не имеет.
В C++17 уже нет copy elision, ну да ладно, не суть важно.
Давай я тебе помогу выдать ответ на мой исходный вопрос. Задам два вопроса (речь про C++17+):
1. При NRVO, переменная result внутри функции и someDictionary вне — обозначают один и тот же объект?
2. Если ответ на предыдущий вопрос утвердительный, то тогда: этот объект константный или нет? (Объяснить почему)
BFE>Если в стандарте описано что-то другое, то этот стандарт надо подправить, а не поведение менять.
Re[99]: Когда это наконец станет defined behavior?
, надо описать поведение первого кода. Только не "эмпирически".
Ну так опишите. И первого, и второго. И найдите отличия. Как найдете можно будет обсудить. Если будет что, поскольку есть сомнения, что найдете.
σ>Я предметно дохрена написал.
Вам кажется. Цитата из стандарта про то, что такое константный объект -- это лишь цитата из стандарта.
В стандарте иногда описывали вещи, которые на практике не существовали.
И не описывали вещи, которыми широко пользовались, а потом пришлось добавлять туда std::launder, std::start_lifetime_as и т.д.
Re[97]: Когда это наконец станет defined behavior?
Здравствуйте, so5team, Вы писали:
S>Я был бы признателен, если бы кто-нибудь объяснил откуда может взяться UB и вообще как результирующий константный объект может рассматриваться до завершения работы порождающей его функции.
UB может взяться, понятное дело, из стандарта. Если внутри стандарта есть противоречие или же неоднозначное прочтение, то вот и UB. Первый раз, что ли?
Конкретно по данному примеру, если подходить формально, то после всех оптимизаций должен создаваться ровно один объект. Константный объект, который нельзя менять и который изменяется после своего создания. Чтобы проверить, есть тут формальное UB или нет, надо половину стандарта прочитать и простить понять. При этом надо нигде не ошибиться в том, что авторы понимали под теми словами, что написали.
И да, формально может оказаться, что вообще константный объект не может быть создан, если у него конструктор нетривиальный.
И каждый день — без права на ошибку...
Re[96]: Когда это наконец станет defined behavior?
Если затем ссылаться на map только через someDictionaryRef — получим полную идентичность до совпадений даже имён (если уж к именам придрался).
V>и применяемый тип относится к ссылке но не к объекту
Ссылка на объект может быть интерпретирована как неотличимая от объекта — это почему компилятор не обязан заводить переменную-ссылку в памяти, если он "видит" её инициализацию, и это прямо по стандарту.
То бишь, хотя в примере выше у нас две переменные, на стеке будет выделено место только для первой из них, а ссылка someDictionaryRef будет использоваться сугубо как алиас имени someDictionary.
(то же самое касается ссылок, инициализированных другими ссылками — они часто "схлопываются" в один алиас времени компиляции)
V>при этом сам объект (созданный в __buildMap над __buildMap_result) — уже не константный
Не "уже не константный", а "еще не константный"
V>таким образом, гипотетическое UB из исходника никак не возможно в развертке так как объект перестал быть константным
Гипотетическое UB невозможно в обоих случаях, т.к. оба случая полностью эквивалентны.
Развёртка показала последовательность происходящего, где константное ссылание на объект возможно только после того, как закончилось мутирование объекта.
После инициализации константной ссылки никакое мутирование не происходит, значит нет и UB.
Re[100]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
σ>>>Ты тролль или дурачок? https://timsong-cpp.github.io/cppwp/n4868/dcl.type.cv#4.sentence-1
S>>Только вот фишка в том, что до выхода из функции нет никакого константного объекта. Он появляется только когда функция закончилась.
σ>Это когда нет NRVO. (И то, скорее константный объект появляется всё-таки до вызова функции, а его инициализация заканчивается (и, следовательно, лайфтайм начинается) после вызова. Ну это так, детали, хер с ними).
До вызова функции может появится разве что место под объект.
σ>А если есть NRVO, то теперь переменная вне функции и внутри, вместо обозначения двух разных объектов, начинают обозначать один и тот же. Я выше кидал цитату про two different ways of referring to the same object.
Еще раз: переменной вне нет пока порождающая функция не завершилась. Место под переменную есть, переменной нет.
S>>Так что UB будет только если мы попробуем поменять константный объект уже после завершения функции из которого мы объект вернули. Но не до того как.
σ>И каким же образом объект вдруг поменяет свою константность?
Не поменяет, а приобретет. Точно так же, как объект приобретает константность после завершения его инициализации.
S>>Ну и я был бы признателен, если бы вы объяснили несведующему, как так получается, что объект константный, но во время работы его конструктора у нас this указывает отнюдь не на константный объект
σ>this во время конструкции константного объекта указаывает, внезапно, на константный объект.
А тот факт, что якобы константный объект можно менять, вам жить не мешает? Или эмпирический опыт вы отвергаете как класс?
S>>изменение состояния внутри конструктора через этот указатель никакое не UB.
σ>Потому что так написано в стандарте https://timsong-cpp.github.io/cppwp/n4868/class.ctor.general#5
Ну так там же и написано, что const на время работы конструктора на объект не распространяется. Т.е. пока инициализация не завершилась нет никакого константного объекта.
Re[103]: Когда это наконец станет defined behavior?
, надо описать поведение первого кода. Только не "эмпирически".
S>Ну так опишите. И первого, и второго. И найдите отличия. Как найдете можно будет обсудить. Если будет что, поскольку есть сомнения, что найдете.
Вроде всё началось с того, что я задал вопрос про константность объекта. Это часть описания. Т.е. у меня как бы вопрос как правильно описать.
Зачем ты мне на это пишешь S>Ну так опишите
Ты же понимаешь, что это в принципе неправильно?
Нет ответа, ну, иди мимо
σ>>Я предметно дохрена написал.
S>Вам кажется. Цитата из стандарта про то, что такое константный объект -- это лишь цитата из стандарта.
S>В стандарте иногда описывали вещи, которые на практике не существовали. S>И не описывали вещи, которыми широко пользовались, а потом пришлось добавлять туда std::launder, std::start_lifetime_as и т.д.
Ты уже докатился почти что до резонёрства.
Re[97]: Когда это наконец станет defined behavior?
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, vopl, Вы писали:
V>>представленная развертка существенно не эквивалентна исходнику, в исходном варианте имя someDictionary означает объект, и тип этого объекта const std::map<int, int> V>>в развертке же это имя означает ссылку, и применяемый тип относится к ссылке но не к объекту, при этом сам объект (созданный в __buildMap над __buildMap_result) — уже не константный
S>Простите за грубость
ничего страшного, прощаю
S>, но когда вы в исходном коде видите: S>
S>const std::map<int, int> someName;
S>
S>то кто вам гарантирует, что идентификатор someName означает что-то кроме ссылки после прохода оптимизатора?
похоже, мы разговариваем на разных языках.. Причем тут оптимизатор — категорически не понимаю. Есть язык, у него есть некие эталонные правила — стандарт. Исходный замес бы исключительно возле этого аспекта. Оптимизатор, линкер, та-или-иная реализация компилятора и прочий тул — это все конечно имеет место быть, но к теме не относится.
Непосредственно в приведенном кусочке — объявляется имя someName и означаемый им объект, этот oбъект имеет тип const std::map<int, int>. Никаких ссылок тут нет. Чтобы работать со ссылками нужно явно использовать ссылочный тип, например так
const std::map<int, int>& someName = blabla;
S> И вообще хоть что-то да значит?
V>>таким образом, гипотетическое UB из исходника никак не возможно в развертке так как объект перестал быть константным
S>Я был бы признателен, если бы кто-нибудь объяснил откуда может взяться UB и вообще как результирующий константный объект может рассматриваться до завершения работы порождающей его функции.
struct S { int i; };
S f()
{
S s;
s.i = 0; // гипотетическое UB тутreturn s; // NRVO
}
const S t = f(); // NRVO
почему тут подозревается UB:
1. имеем NRVO, а в этом случае возвращаемый из функции объект и объект внитри функции — это один и тот же объект (ссылку выше приводил ув. σ)
2. тип объекта определяется по декларации этого объекта. Имеем две декларации, во второй объект имеет константный тип, следовательно, компилятор вполне может его (объект) трактовать как константный
3. следовательно, объект, обозначенный именем s (который в силу NRVO есть тот же самый что и t) — можеть быть оттрактован компилятором как константный
4. модификация полей константного объекта — UB (ссылку выше приводил ув. σ)
5. следовательно, модификация s.i = 0 подозревается в UB
S>А еще было бы круто если бы кто-нибудь из почитателей святой буквы стандарта
зачем ерничать? Я постараюсь ответить на все моменты по сабжу если это будет в моих силах, но только чтобы это все происходило в инженерном ключе а не в эмоциональном
S> наконец-то объяснил простую штуку: S>
S>работает конструктор константного объекта, но сам объект в это время нифига не константа.
ув. σ выше по теме приводил норму для этого случая, лень искать. Вкратце простыми словами — конструктору в этом случае дадено исключительное право сцецифическим образом плевать на константность.
S>А то доказывать, что термин "implicitly creates" понятен всем и каждому, вот прям горазды.
Лично я когда зашел в тему — вообще не задумывался ни про какие там "implicitly creates", вообще слова такого даже не знал. Ув. σ его употребил — я пошел в стандарте посмотреть что оно означает, почитал-ознакомился, оказалось это вполне четкая штуковина. То есть, "понятен всем и каждому" — лично мне небыло ничего понятно.
S>А ответить на простые вопросы так "покажите мне текст стандарта".
и судя по всему это правильно. Именно стандарт и определяет все эти аспекты поведения, с него и надо начинать
Re[97]: Когда это наконец станет defined behavior?
Здравствуйте, so5team, Вы писали:
S>А то доказывать, что термин "implicitly creates" понятен всем и каждому, вот прям горазды. А ответить на простые вопросы так "покажите мне текст стандарта".
Можно отсылать прямо в home стандарта, в рекомендуемое предисловие к материалу: https://isocpp.org/tour
И там примерно такое (гуглоперевод):
Предисловие к Языку программирования C++, 4-е изд.
Эта книга предназначена для трех аудиторий:
Программисты C++, которые хотят знать, что предлагает последний стандарт ISO C++,
Программисты на C, которым интересно, что C++ предлагает помимо C, и
Люди, имеющие опыт работы с языками приложений, такими как Java, C#, Python и Ruby, которые ищут что-то «ближе к машине» — что-то более гибкое, что-то с лучшей проверкой во время компиляции или что-то с большей производительностью.
Естественно, эти три группы не являются непересекающимися — профессиональный разработчик программного обеспечения владеет более чем одним языком программирования.
Эта книга предполагает, что ее читатели — программисты. Если вы спросите: «Что такое цикл for?» или «Что такое компилятор?» тогда эта книга (пока) не для вас; вместо этого я рекомендую книгу Programming: Principles and Practice Using C++ , чтобы начать работу с программированием на C++. Кроме того, я предполагаю, что читатели уже достигли определенной зрелости как разработчики программного обеспечения. Если вы спросите: «Зачем вообще тестировать?» или сказать: «Все языки в основном одинаковы; просто покажите мне синтаксис» или уверены, что существует единственный язык, идеально подходящий для любой задачи, эта книга не для вас.
Re[101]: Когда это наконец станет defined behavior?
S>>>Ну и я был бы признателен, если бы вы объяснили несведующему, как так получается, что объект константный, но во время работы его конструктора у нас this указывает отнюдь не на константный объект σ>>this во время конструкции константного объекта указаывает, внезапно, на константный объект.
V>this указывает на неконстантный объект, в чём ты можешь легко убедиться.
this указывает на константный объект, в чём ты можешь легко убедиться.
S>>>изменение состояния внутри конструктора через этот указатель никакое не UB. σ>>Потому что так написано в стандарте https://timsong-cpp.github.io/cppwp/n4868/class.ctor.general#5
V>И в чём твоя проблема? V>Гугл-переводчик сломался? V>RV-оптимизация происходит, на секундочку, над конструктором копирования. V>Или это тебе не конструктор уже? ))
Ты, походу, уже совсем почти бессвязную белеберду выдаёшь.
Re[96]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
σ>Nice copium.
Комитета.
σ>Не думаю, что это описание подходит для C++17 и выше. И ты отвечаешь не на то, про что я спросил. Видимо, тоже не понял, про что вопрос.
Я понял, что вы спросили. Вы не поняли моего ответа.
BFE>>NRVO — это про то, что возвращает функция, а не про инициализацию константного объекта обозначенного именем someDictionary. То, что потом случается сopy elision к самой функции отношения уже не имеет. σ>В C++17 уже нет copy elision, ну да ладно, не суть важно.
Да, я знаю, что после C++17 всё это сильно запутали. Стало хуже.
σ>Давай я тебе помогу выдать ответ на мой исходный вопрос.
Лучше скажите, вот в этом коде:
struct A
{
int m{};
A() { m = 1; }
}
const A a;
константный объект a меняется во время своей инициализации. А ведь это UB — константный объект менять нельзя! σ>Задам два вопроса (речь про C++17+): σ>1. При NRVO, переменная result внутри функции и someDictionary вне — обозначают один и тот же объект? σ>2. Если ответ на предыдущий вопрос утвердительный, то тогда: этот объект константный или нет? (Объяснить почему)
Давайте я вам подсказку дам, где вы ошибаетесь. Вот она: lifetime
И каждый день — без права на ошибку...
Re[98]: Когда это наконец станет defined behavior?
Здравствуйте, B0FEE664, Вы писали:
BFE>И да, формально может оказаться, что вообще константный объект не может быть создан, если у него конструктор нетривиальный.
Ну да, докатиться можно и до этого в рассуждениях. ))
Но тут простой ответ в том, что ссылку на такой объект можно получить только после завершения конструирования, кроме как в случае глобальных переменных, о чём было сказано cразу же.