Здравствуйте, σ, Вы писали:
σ>>>this во время конструкции константного объекта указаывает, внезапно, на константный объект. V>>this указывает на неконстантный объект, в чём ты можешь легко убедиться. σ>this указывает на константный объект, в чём ты можешь легко убедиться.
Константность проверяется от противного — я могу вызвать внешнюю ф-ию через неконстантный this безо-всяких кастов.
V>>И в чём твоя проблема? V>>Гугл-переводчик сломался? V>>RV-оптимизация происходит, на секундочку, над конструктором копирования. V>>Или это тебе не конструктор уже? )) σ>Ты, походу, уже совсем почти бессвязную белеберду выдаёшь.
В отсутствии понимания любая примитивщина кажется белибердой. ))
Ликбез: RVO — это про избегание операции копирования.
Re[98]: Когда это наконец станет defined behavior?
Здравствуйте, vopl, Вы писали:
V>вот тут внимательно посмотри V>в исходном примере имеем const std::map<int, int> someDictionary = buildMap(); V>в развертке же ссылка
Которой по-факту не существует — под неё не выделяется память.
Прямо по стандарту компилятору позволяется рассматривать такую ссылку как алиас другой переменной, если ссылка инициализируется именно так — в области видимости ссылаемой переменной/значения.
V>без эмоций подумай эту разницу.
В этой разнице надо ориентироваться.
Просто коллега не был в курсе, что ты этого не знаешь, подразумевал как само собой разумеющееся.
V>Конкретнее — в исходном случае получаем NRVO, а следовательно получаем и ситуацию с двумя декларациями одного и того же объекта, одну внутри функции вторую снаружи.
С тремя значениями объекта, если быть точнее.
В исходном примере нивелируются 2 конструктора копирования:
1. при возврате значения из ф-ии во временный объект;
2. при конструировании переменной от временного объекта.
V>И одна из них делает объект константным.
При возврате значения во временный объект тип объекта не меняется, кстате.
(хотя это и не принципиально)
V>Один и тот же объект. Внимательно присмотрись, без предубеждений
Смотреть надо только на код.
В коде прямо прописано, что вызывается конструктор копирования от временного значения, возвращаемого ф-ей buildMap().
Попробуй запретить конструктор копирования, чтобы убедиться: http://www.rsdn.org/forum/cpp/8585111.1
В дебажной версии так и будет 2 конструктора копирования.
Re[104]: Когда это наконец станет defined behavior?
σ>Если ты про область видимости переменных s и t, σ>
struct S { int i; };
σ>S f();
σ>const S t = f();
σ>S f()
σ>{
σ> S s;
σ> s.i = 0;
σ> return s;
σ>}
σ>то вот, внутри функции s и t доступны "одновременно".
Наконец-то интересный пример.
Добиваем мусорными полями, чтоб объект не мог вернуться в регистрах, и...
#include <stdio.h>
#include <stdlib.h>
struct S { int i; double d; int j; };
S f();
const S t = f();
S f()
{
S s;
printf("t.i=%i\n", t.i);
s.i = 42;
printf("t.i=%i\n", t.i);
return s;
}
int main() {
return 0;
}
Вывод:
t.i=0
t.i=42
Правда константность тут нипричом. Если убрать её, будет то же самое. Короче я всё ещё жду UB
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[98]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
σ>>>1. При NRVO, переменная result внутри функции и someDictionary вне — обозначают один и тот же объект? V>>Не одновременно, и этого достаточно. σ>Чё ты цепляешься за это "не одновременно" как за соломинку?
Не-не-не, это ты пытаешься съехать, мол, "это не я накосячил, это так прописано в стандарте".
В стандарте для UB надо пытаться изменять константный объект, а для этого надо каким-либо образом реинтерпретировать объект или его память как неконстантную.
σ>"Не одновременно" это ты про то, что инициализируемая константная переменная вне области видимости тела функции? Тоже мне, проблема: σ>
struct S { int i; };
σ>S f();
σ>const S t = f();
σ>S f()
σ>{
σ> S s;
σ> s.i = 0;
σ> return s;
σ>}
"Проблема" никуда не делась — после выхода из f переменной s более не существует, а переменная t только появляется через вызов конструктора копирования.
V>>Ты бы оперировал полностью подробностями: σ>Ты подробностями называешь детали реализации?
Детали RVO
σ>Нахер ими вообще оперировать, рассуждая о семантике C++, можешь объяснить сперва?
О чём тебе и говорилось изначально — ты можешь рассматривать свой код как будто в нём нет никакого RVO. ))
σ>Семантика C++ не зависит от того, подготавливается там область памяти, или область хуямяти, или программа с бумажкой и карандашом интерпретируется.
Верно, но с одной оговоркой про побочные эффекты в конструкторах/деструкторах.
И об этих пообочных эффектах в стандарте говорится прямо — дабы ты не прозевал подробности. ))
А так-то да, можно договориться до чего угодно, если лезть "унутре", ведь при вызове банальных переопределённых виртуальных ф-ий даже происходит даункаст ссылочного типа this, и ничего! Все живы! Потому что эта механика спрятана, гарантируется корректное преобразование типа (вплоть до смещения адреса при множественном наследовании) и прочие тонкости, которые не должны тебя волновать.
Так же и в случае RVO — корректность кода пострадать не должна, если не будет побочных эфффектов.
Остальные твои попытки заглянуть под капот — спекуляции чистой воды. ))
Но даже и с учётом этой попытки тебя уже тыкали в то, что ты не можешь оперировать ссылкой/переменной на константный объект, бо этой ссылки еще не существует.
Здравствуйте, vopl, Вы писали:
V>>>при этом сам объект (созданный в __buildMap над __buildMap_result) — уже не константный V>>Не "уже не константный", а "еще не константный" V>Имено "уже не константный". В исходном примере он был константный, а потом ув. so5team его развернул и объект стал не костантным.
Дудки, so5team показал императивные шаги происходящего достаточно близко к происходящему (за исключением явного выделения места в стеке — ф-ия обычно заранее знает размер своего локального фрейма стека и заранее раскидывает по нему адреса переменных).
В исходном примере константного объекта еще не было, было лишь место под него.
Похоже, тебя смущает запись присваивания справа налево. ))
Кстате, были как-то предложения добавить оператор записи/присваивания в конце выражения, а не в начале, но сдулось.
В общем, в исходном примере сначала вычисляется выражение справа, а только потом происходит конструирование объекта слева.
До окончания конструирования объекта у тебя нет возможности оперировать его переменной — что и показала развёртка от so5team.
Кстате, в исходном примере можно было переделать на ссылку, чтобы ты по мелочам не придирался:
const std::map<int, int> & map = buildMap();
И ничего не изменится, после всех оптимизаций (просто в этом случае будет одна оптимизация копирования, а не две, как в исходном примере).
Re[94]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
V>>Ты на вопрос не ответил. σ>Конструируя объект типа const T, конструируем константный объект, т.к. по определению объект типа const T это константный объект (const object).
Ты повторяешь это уже 20-й раз, и 20-й раз тебя спрашивают: "Ну, и???"
Ведь не бывает конструктора объекта const T, есть конструктор просто T.
И вообще, это придурь уже какая-то, бо тебе уже подсказывали (с самого начала твоей упёртости), что конструирование — это императивный пошаговый процесс, в общем случае требующий последовательного изменения полей (то бишь состояния) объекта.
До окончания конструирования объект считается неинициализированным, т.е. его нельзя рассматривать как объект — это просто куча байт в памяти.
Соотв., все рассуждения про эту кучу байт как про объект — ошибочны.
А придурь она будет в любом случае, бо эти вещи ты и сам должен понимать.
А если не понимаешь — то молча внимаешь и очень вежливо спрашиваешь, изо всех сил пытаясь понять, что тебе говорят, бгг...
Ты должен был дать строгое определение возникающему UB, но ты его так и не дал.
И никогда дать не сможешь, ес-но, бо стоит тебе только попытаться и ты увидишь, как облажался. ))
Причём, тебе в первом же ответе подсказали, где именно ты облажался — ты пытался рассуждать так, будто константная и неконстантная отсылка к объекту валидны одновременно, дважды бгг...
Re[105]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
S>>Еще раз: переменной вне нет пока порождающая функция не завершилась. Место под переменную есть, переменной нет. σ>Какое ещё место под переменную? Ты случайно не путаешь переменные и объекты?
В данном случае (при хранении по значению) это одно и то же.
Re[107]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
S>>Автоматически после завершения работы конструктора. σ>Т.е при завершении работы конструктора меняется тип объекта?
Добавляется модификатор типа, считай что объект "запечатывается".
И это абсолютно законно, бо до завершения конструктора ты не можешь извне пользоваться этим объектом.
По-факту, не существует разницы м/у константным и неконстантым объектом с т.ч. занимаемой им памяти и даже прикладных инвариантов.
Разница есть в системе допущений, которыми вправе пользоваться компилятор в процессе оптимизации, например, не запрашивать некие поля или не вычислять некие значения от полей объекта повторно. Т.е. потенциальное UB возможно из-за неверных этих допущений, если горе-программист хакнул собственный константный объект, радостно обманув глупый компилятор.
Re[104]: Когда это наконец станет defined behavior?
Здравствуйте, vopl, Вы писали:
V>Во первых, не вижу необходимости кому либо что то демонстрироать. Обрати внимание, я называю сабжевое UB "гипотетическим", "подозреваемым".
И какое неопределённое поведение тут может быть?
Пусть даже самое гипотетическое?
Re[110]: Когда это наконец станет defined behavior?
Здравствуйте, vopl, Вы писали:
V>Вероятно, это недоработка языка.
Или собственное непонимание, ведь стандарт описан не для домохозяек, а для специалистов с неким ненулевым бэкграундом.
V>Примерно такая же, что и привела к сабжевому гипотетическому UB — стандарт определил: V>1. что тип объекта определяется его декларацией V>2. модифицировать константный объект — UB V>3. и тут добавили положение про NRVO, которое сделало возможным один и тот же объект задекларировать два раза, причем по разному (с константностью и без). И вот этот третий пункт с учетом предыдущих двух формирует всю обсуждаемую в текущей подветке котовасию
Это так не работает, реально. ))
Абсолютно любое потенциальное UB из стандарта может быть достаточно легко объяснено "на пальцах" — откуда может взяться расхождение описанного в коде и реально происходящего.
Конкретно в этой ситуации лично я не вижу потенциального UB, которое можно было бы размуно объяснить.
(оговорку про использование неинициализированных глобальных переменных сделал сразу же, но эта оговорка справедлива к любым таким переменным, необязательно константным)
В итоге, ни ты, ни твой союзник не показали сути этого потенциального UB, кроме как через малосвязанные пункты из стандарта, где эту связь вы насосали из пальца.
Суть вашего насоса вам сразу же сообщили и даже показали в "развёртке" — ссылание на объект неодновременно, а подразумеваемый вами UB должен случиться при одновременном наличии константной и неконстантной отсылки к объекту.
В этом месте вы упёрлись и давай нас развлекать. ))
V>Это дело вкуса. Для меня, например, стандарт — это правила игры в язык C++.
стандарт описан не для домохозяек, а для специалистов с неким ненулевым бэкграундом
V>Если кто то хочет играть в игру на основе собственного понимания правил — пожалуйста, но стандарт — это источник первичного смысла в ней.
Только надо делать скидку на то, что стандарт С++ использует достаточно вольную трактовку понятия "объект", где на самом деле это не объект из ООП и даже не объект в терминологии С++ (где объект — это экземпляр класса, структуры или объединения), а просто любой экземпляр любого типа.
Re[98]: Когда это наконец станет defined behavior?
σ>И что «lifetime»? Он начинается внутри функции, после инициализации result.
Когда начинается lifetime объекта someDictionary ? Тогда, когда заканчивается конструирование объекта.
В выражении const std::map<int, int> someDictionary = buildMap(); вызов buildMap() sequenced before инициализации someDictionary, а значит значение для инициализации должно быть получено до начала lifetime объекта someDictionary. А до этих пор константный объект можно модифицировать.
И каждый день — без права на ошибку...
Re[99]: Когда это наконец станет defined behavior?
σ>>И что «lifetime»? Он начинается внутри функции, после инициализации result. BFE>Когда начинается lifetime объекта someDictionary ? Тогда, когда заканчивается конструирование объекта.
Ну. При NRVO, оно заканчивается на std::map<int, int> result;.
BFE>В выражении const std::map<int, int> someDictionary = buildMap(); вызов buildMap() sequenced before инициализации someDictionary, а значит значение для инициализации должно быть получено до начала lifetime объекта someDictionary. А до этих пор константный объект можно модифицировать.
Получается, result.insert(42, 43); — UB, т.к. после старта лайфтайма?
Или объект сначала вроде как создаётся константным (const std::map<int, int> someDictionary), но потом становится неконстантным (std::map<int, int> result;), а опять константным не становится, и его можно менять даже после const std::map<int, int> someDictionary = buildMap();?