Re[102]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 20:17
Оценка:
Здравствуйте, σ, Вы писали:

σ>>>this во время конструкции константного объекта указаывает, внезапно, на константный объект.

V>>this указывает на неконстантный объект, в чём ты можешь легко убедиться.
σ>this указывает на константный объект, в чём ты можешь легко убедиться.

Константность проверяется от противного — я могу вызвать внешнюю ф-ию через неконстантный this безо-всяких кастов.


V>>И в чём твоя проблема?

V>>Гугл-переводчик сломался?
V>>RV-оптимизация происходит, на секундочку, над конструктором копирования.
V>>Или это тебе не конструктор уже? ))
σ>Ты, походу, уже совсем почти бессвязную белеберду выдаёшь.

В отсутствии понимания любая примитивщина кажется белибердой. ))
Ликбез: RVO — это про избегание операции копирования.
Re[98]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 20:26
Оценка:
Здравствуйте, 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?
От: T4r4sB Россия  
Дата: 21.08.23 20:32
Оценка: +1 -2 :))
Здравствуйте, σ, Вы писали:


σ>Если ты про область видимости переменных 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?
От: vdimas Россия  
Дата: 21.08.23 20:33
Оценка:
Здравствуйте, σ, Вы писали:

σ>>>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 — корректность кода пострадать не должна, если не будет побочных эфффектов.
Остальные твои попытки заглянуть под капот — спекуляции чистой воды. ))
Но даже и с учётом этой попытки тебя уже тыкали в то, что ты не можешь оперировать ссылкой/переменной на константный объект, бо этой ссылки еще не существует.
Отредактировано 21.08.2023 21:30 vdimas . Предыдущая версия . Еще …
Отредактировано 21.08.2023 21:30 vdimas . Предыдущая версия .
Re[98]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 20:41
Оценка:
Здравствуйте, vopl, Вы писали:

V>>>при этом сам объект (созданный в __buildMap над __buildMap_result) — уже не константный

V>>Не "уже не константный", а "еще не константный"
V>Имено "уже не константный". В исходном примере он был константный, а потом ув. so5team его развернул и объект стал не костантным.

Дудки, so5team показал императивные шаги происходящего достаточно близко к происходящему (за исключением явного выделения места в стеке — ф-ия обычно заранее знает размер своего локального фрейма стека и заранее раскидывает по нему адреса переменных).

В исходном примере константного объекта еще не было, было лишь место под него.
Похоже, тебя смущает запись присваивания справа налево. ))

Кстате, были как-то предложения добавить оператор записи/присваивания в конце выражения, а не в начале, но сдулось.

В общем, в исходном примере сначала вычисляется выражение справа, а только потом происходит конструирование объекта слева.
До окончания конструирования объекта у тебя нет возможности оперировать его переменной — что и показала развёртка от so5team.

Кстате, в исходном примере можно было переделать на ссылку, чтобы ты по мелочам не придирался:
const std::map<int, int> & map = buildMap();

И ничего не изменится, после всех оптимизаций (просто в этом случае будет одна оптимизация копирования, а не две, как в исходном примере).
Re[94]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 20:49
Оценка:
Здравствуйте, σ, Вы писали:

V>>Ты на вопрос не ответил.

σ>Конструируя объект типа const T, конструируем константный объект, т.к. по определению объект типа const T это константный объект (const object).

Ты повторяешь это уже 20-й раз, и 20-й раз тебя спрашивают: "Ну, и???"
Ведь не бывает конструктора объекта const T, есть конструктор просто T.

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

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

А придурь она будет в любом случае, бо эти вещи ты и сам должен понимать.
А если не понимаешь — то молча внимаешь и очень вежливо спрашиваешь, изо всех сил пытаясь понять, что тебе говорят, бгг...


σ>Вот определение: https://timsong-cpp.github.io/cppwp/n4868/basic.type.qualifier#def:object,const.

σ>Могу даже скопировать определение сюда
>> A const object is an object of type const T
σ>Охренеть как сложно, да?

Летели два крокодила, один зеленый, другой на север.
Тоже ничего сложного, но очень глупо. ))


σ>>>Его ты, видимо, тоже не смог понять

V>>Так нечего понимать — ты не даёшь строгих определений
σ>Вот определение, даю в третий, если не больше, раз: https://timsong-cpp.github.io/cppwp/n4868/basic.type.qualifier#def:object,const. Строже него нет.

Ты должен был дать строгое определение возникающему UB, но ты его так и не дал.
И никогда дать не сможешь, ес-но, бо стоит тебе только попытаться и ты увидишь, как облажался. ))

Причём, тебе в первом же ответе подсказали, где именно ты облажался — ты пытался рассуждать так, будто константная и неконстантная отсылка к объекту валидны одновременно, дважды бгг...
Re[105]: Когда это наконец станет defined behavior?
От: σ  
Дата: 21.08.23 20:50
Оценка:
TB>Правда константность тут нипричом. Если убрать её, будет то же самое.
Л — логика
Re[106]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 21.08.23 20:51
Оценка:
Здравствуйте, σ, Вы писали:

TB>>Правда константность тут нипричом. Если убрать её, будет то же самое.

σ>Л — логика

Так а где обещанное тобой UB?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[102]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 20:54
Оценка: -1 :)
Здравствуйте, σ, Вы писали:

S>>Еще раз: переменной вне нет пока порождающая функция не завершилась. Место под переменную есть, переменной нет.

σ>Какое ещё место под переменную? Ты случайно не путаешь переменные и объекты?

В данном случае (при хранении по значению) это одно и то же.
Re[107]: Когда это наконец станет defined behavior?
От: σ  
Дата: 21.08.23 20:59
Оценка:
TB>Так а где обещанное тобой UB?
Так а где описание ожидаемой логики?
Re[108]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 21.08.23 21:00
Оценка: -1 :))
Здравствуйте, σ, Вы писали:

σ>Так а где описание ожидаемой логики?


Плейграунд любой открой и запусти. Одно и то же в дебаге, релизе, с константой, без. Где UB?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[104]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 21:02
Оценка:
Здравствуйте, σ, Вы писали:

S>>Автоматически после завершения работы конструктора.

σ>Т.е при завершении работы конструктора меняется тип объекта?

Добавляется модификатор типа, считай что объект "запечатывается".
И это абсолютно законно, бо до завершения конструктора ты не можешь извне пользоваться этим объектом.

По-факту, не существует разницы м/у константным и неконстантым объектом с т.ч. занимаемой им памяти и даже прикладных инвариантов.

Разница есть в системе допущений, которыми вправе пользоваться компилятор в процессе оптимизации, например, не запрашивать некие поля или не вычислять некие значения от полей объекта повторно. Т.е. потенциальное UB возможно из-за неверных этих допущений, если горе-программист хакнул собственный константный объект, радостно обманув глупый компилятор.
Re[104]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 21:04
Оценка:
Здравствуйте, σ, Вы писали:

σ>то вот, внутри функции s и t доступны "одновременно".


Переменная t внутри f еще не существует, а значит недоступна.
Re[104]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 21:07
Оценка:
Здравствуйте, σ, Вы писали:

σ>Вроде всё началось с того, что я задал вопрос про константность объекта.


На что сразу же получил ответ, что объекта, который ты имел ввиду, еще не существует в рассматриваемой точке инициализации.
Re[109]: Когда это наконец станет defined behavior?
От: σ  
Дата: 21.08.23 21:09
Оценка:
σ>>Так а где описание ожидаемой логики?

TB>Плейграунд любой открой и запусти. Одно и то же в дебаге, релизе, с константой, без.


Теперь тебе осталось всего ничего: предоставить пруф, что такое и должно быть согласно спеке.
Re[100]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 21:09
Оценка:
Здравствуйте, vopl, Вы писали:

V>Во первых, не вижу необходимости кому либо что то демонстрироать. Обрати внимание, я называю сабжевое UB "гипотетическим", "подозреваемым".


И какое неопределённое поведение тут может быть?
Пусть даже самое гипотетическое?
Re[110]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 21.08.23 21:14
Оценка:
Здравствуйте, σ, Вы писали:

σ>Теперь тебе осталось всего ничего: предоставить пруф, что такое и должно быть согласно спеке.


Вот пруф для балаболов-любителей тупой демагогии: http://godzilla.vfose.ru/
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[100]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 21.08.23 21:19
Оценка:
Здравствуйте, vopl, Вы писали:

V>Вероятно, это недоработка языка.


Или собственное непонимание, ведь стандарт описан не для домохозяек, а для специалистов с неким ненулевым бэкграундом.


V>Примерно такая же, что и привела к сабжевому гипотетическому UB — стандарт определил:

V>1. что тип объекта определяется его декларацией
V>2. модифицировать константный объект — UB
V>3. и тут добавили положение про NRVO, которое сделало возможным один и тот же объект задекларировать два раза, причем по разному (с константностью и без). И вот этот третий пункт с учетом предыдущих двух формирует всю обсуждаемую в текущей подветке котовасию

Это так не работает, реально. ))

Абсолютно любое потенциальное UB из стандарта может быть достаточно легко объяснено "на пальцах" — откуда может взяться расхождение описанного в коде и реально происходящего.

Конкретно в этой ситуации лично я не вижу потенциального UB, которое можно было бы размуно объяснить.
(оговорку про использование неинициализированных глобальных переменных сделал сразу же, но эта оговорка справедлива к любым таким переменным, необязательно константным)

В итоге, ни ты, ни твой союзник не показали сути этого потенциального UB, кроме как через малосвязанные пункты из стандарта, где эту связь вы насосали из пальца.
Суть вашего насоса вам сразу же сообщили и даже показали в "развёртке" — ссылание на объект неодновременно, а подразумеваемый вами UB должен случиться при одновременном наличии константной и неконстантной отсылки к объекту.

В этом месте вы упёрлись и давай нас развлекать. ))


V>Это дело вкуса. Для меня, например, стандарт — это правила игры в язык C++.


стандарт описан не для домохозяек, а для специалистов с неким ненулевым бэкграундом



V>Если кто то хочет играть в игру на основе собственного понимания правил — пожалуйста, но стандарт — это источник первичного смысла в ней.


Только надо делать скидку на то, что стандарт С++ использует достаточно вольную трактовку понятия "объект", где на самом деле это не объект из ООП и даже не объект в терминологии С++ (где объект — это экземпляр класса, структуры или объединения), а просто любой экземпляр любого типа.
Re[98]: Когда это наконец станет defined behavior?
От: B0FEE664  
Дата: 21.08.23 22:14
Оценка: +1
Здравствуйте, σ, Вы писали:

  Скрытый текст
std::map<int, int> buildMap() {
    std::map<int, int> result;

    result.insert(42, 43); 
    ...
    return result;
}

const std::map<int, int> someDictionary = buildMap();

σ>И что «lifetime»? Он начинается внутри функции, после инициализации result.
Когда начинается lifetime объекта someDictionary ? Тогда, когда заканчивается конструирование объекта.
В выражении const std::map<int, int> someDictionary = buildMap(); вызов buildMap() sequenced before инициализации someDictionary, а значит значение для инициализации должно быть получено до начала lifetime объекта someDictionary. А до этих пор константный объект можно модифицировать.

И каждый день — без права на ошибку...
Re[99]: Когда это наконец станет defined behavior?
От: σ  
Дата: 22.08.23 00:03
Оценка: :)
σ>>И что «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();?
Отредактировано 22.08.2023 0:09 σ . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.