Re[101]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 22.08.23 15:24
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, vopl, Вы писали:


V>>аа.. я ориентировался на это
Автор: σ
Дата: 16.08.23


V>>Выше приводил конкретные 5 пунктов, даже с косвенной отсылкой на стандарт, посредством которых мною допускается гипотеза сабжевого UB. То есть, те 5 пунктов объясняют, каким образом допускается гипотеза про UB. Я не просил никаких ссылок на стандарт, наоборот, готов предоставить их явно для обоснования тех или иных своих тезисов. На счет того что "мне кажется" — тут да, мне действительно кажется что здесь может быть оттрактовано UB, и приведенные выше 5 пунктов объясняют каким именно образом.


R>Смотри, какая штука получается, давай еще раз посмотрим на этот абзац в стандарте:


R>https://timsong-cpp.github.io/cppwp/class.copy.elision#1


R>

R>When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object. If the first parameter of the selected constructor is an rvalue reference to the object's type, the destruction of that object occurs when the target would have been destroyed; otherwise, the destruction occurs at the later of the times when the two objects would have been destroyed without the optimization.


R>Object-то the same, но вот ways are different и это ключевой момент, который покрывает сразу и разницу времен жизни, и разницу в константности.


Время жизни является свойством объекта а не пути к нему. Время жизни определяется исходя из манипкляций с объектом, причем не важно сквозь какой путь. Поэтому, количество этих путей не важно. Объект один — lifetime один.

R> А еще хочу заострить внимание на вот этой фразе: "an implementation is allowed...". То есть, не говорится, что компилятор обязан так сделать — ему это разрешается. И как именно он поступит, так или эдак, программист даже знать не обязан. В итоге программист имеет полное право считать, что в данном случае создаются два (или даже три) объекта, с разными временами жизни и разной константностью.


Стандарт говорит по другому, ты сам чуть выше привел цитату про the same object. На практике это, например, будет проявляться в том что у программиста во внутреннем объекте и во внешнем — то ли одинаковый this (если случилось RVO) то ли разные (если оно не случилось). Так же, к примеру, побочные эффекты в выдавленных конструкторах поскипаются в случае RVO, а без него они останутся. Другими словами, программист не имеет права считать что бъекта будет два/три, он обязан считать что ему будет обстоятельствами непреодолимой силы (an implementation is allowed...) дадено либо два объекта либо один.

R>И правильно тут рядом сказали: NRVO — это разновидность оптимизации, как ни крути.


Ну.. Окей. Утверждение на любителя как по мне. По такой логике можно говорить что Zero-overhead principle, inline — это тоже разновидности оптимизации. Ну и что. Как это можно применить к сабжу?
Re[110]: Когда это наконец станет defined behavior?
От: B0FEE664  
Дата: 22.08.23 15:39
Оценка: :)
Здравствуйте, σ, Вы писали:

BFE>>Если это свойство выкидывается вместе с конструктором, то в коде примера ниже someDictionary вообще не начинает жить, а следовательно, const должен игнорироваться полностью, следовательно объект someDictionary можно менять (ведь его время жизни ещё не началось)


σ>

σ>https://timsong-cpp.github.io/cppwp/n4868/basic.life#7.sentence-4
σ>https://timsong-cpp.github.io/cppwp/n4868/res.on.objects#2

Вы не на то сослались
someDictionary вообще не начинает жить, а вот result — живёт вместо него и его можно менять используя переменную someDictionary.
И каждый день — без права на ошибку...
Re[109]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 22.08.23 15:39
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, vopl, Вы писали:


V>>>> Он относится ко всему copy целиком, со всеми его эффектами, включая связность с lifetime

BFE>>> Ну попробуйте это обосновать.
V>>Ну, обоснование у меня вряд ли получится сформулировать. Вместо обоснования — приведу свою логику рассуждений:
V>>нет оснований полагать что в стандарте под выдавливанием copy пониматся не copy а некий "copy part", так как там не указано, какие именно аспекты copy будут выдавлены а какие — нет. Таким образом я считаю что имеется ввиду весь copy целиком.

BFE>lifetime — это не результат создания объекта. lifetime — это свойство объекта, присущее объекту в некоторые отрезки выполнения программы (от конца конструктора до начала деструктора).


ага

BFE>Если это свойство выкидывается вместе с конструктором, то в коде примера ниже someDictionary вообще не начинает жить


someDictionary не обладает свойством lifetime, потому что он не объект, someDictionary это имя объекта. А объект (помним что это тот самый объект который the same внутри и снаружи) означаемый именем someDictionary уже начал свой lifetime, когда внутри функции завершился конструктор result.

BFE>, а следовательно, const должен игнорироваться


так же смею заметить, константность объекта определяется не по конструктору, она определяется по декларации. А деклараций две, и хрен поймешь какую из них возьмет компилятор. В отсутствии каких либо предпосылок я предполагаю худший вариант, считаю что он возьмет ту которая внешняя, с констанностью (хотя выше по теме ув. σ показывал что и второй вариант — тоже проблемный). И вот в этом случае имеем константный объект (по декларации) с начатым временем жизни (внутри функции отработал конструктор, помним что этот объект the same), подвергается модификации.
Re[102]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 22.08.23 15:40
Оценка: +1
Здравствуйте, vopl, Вы писали:

V>Ну.. Окей. Утверждение на любителя как по мне. По такой логике можно говорить что Zero-overhead principle, inline — это тоже разновидности оптимизации. Ну и что. Как это можно применить к сабжу?


Программист просто не обязан знать, применил ли компилятор NRVO, или не применил, и интерпретация деклараций и кода в целом не должна зависеть от таких деталей.
--
Справедливость выше закона. А человечность выше справедливости.
Re[111]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 22.08.23 15:43
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, σ, Вы писали:


BFE>>>Если это свойство выкидывается вместе с конструктором, то в коде примера ниже someDictionary вообще не начинает жить, а следовательно, const должен игнорироваться полностью, следовательно объект someDictionary можно менять (ведь его время жизни ещё не началось)


σ>>

σ>>https://timsong-cpp.github.io/cppwp/n4868/basic.life#7.sentence-4
σ>>https://timsong-cpp.github.io/cppwp/n4868/res.on.objects#2

BFE>Вы не на то сослались

BFE>someDictionary вообще не начинает жить, а вот result — живёт

Не забываем что someDictionary/result — это лишь имена, у них нет lifetime, они не живут. Lifetime есть только у объекта, который the same и доступен по обоим этим именам. Объект живет. Таким образом, наблюдаемый lifetime у the same object один и тот же независимо через какое имя мы смотрим на объект.
Re[103]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 22.08.23 15:49
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, vopl, Вы писали:


V>>Ну.. Окей. Утверждение на любителя как по мне. По такой логике можно говорить что Zero-overhead principle, inline — это тоже разновидности оптимизации. Ну и что. Как это можно применить к сабжу?


R>Программист просто не обязан знать, применил ли компилятор NRVO, или не применил, и интерпретация деклараций и кода в целом не должна зависеть от таких деталей.


именно так, для программиста этот исход не определен заранее. Аналогично программист не знает заранее, проинлайнит ли компилятор функцию или нет. Я с этим полностью согласен, это можно называть некоей "оптимизацией". Вопрос в другом: как это утверждение может помочь по сабжу (будет объект константным или нет
Автор: σ
Дата: 16.08.23
и затем — если он константный, будет ли UB при доступе к нему на запись после конструирования)?
Re[104]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 22.08.23 15:54
Оценка: +1 :)
Здравствуйте, vopl, Вы писали:

V>именно так, для программиста этот исход не определен заранее. Аналогично программист не знает заранее, проинлайнит ли компилятор функцию или нет. Я с этим полностью согласен, это можно называть некоей "оптимизацией". Вопрос в другом: как это утверждение может помочь по сабжу (будет объект константным или нет
Автор: σ
Дата: 16.08.23
и затем — если он константный, будет ли UB при доступе к нему на запись после конструирования)?


Помочь может очень легко: мы имеем полное право отвечать на эти вопросы в презумпции, что NRVO не примененяется (полагаю, ответы очевидны), а применение NRVO, если таковое произошло, никак не должно повлиять на рассуждения и выводы.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 22.08.2023 16:28 rg45 . Предыдущая версия . Еще …
Отредактировано 22.08.2023 15:55 rg45 . Предыдущая версия .
Re[105]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 22.08.23 16:03
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, vopl, Вы писали:


V>>именно так, для программиста этот исход не определен заранее. Аналогично программист не знает заранее, проинлайнит ли компилятор функцию или нет. Я с этим полностью согласен, это можно называть некоей "оптимизацией". Вопрос в другом: как это утверждение может помочь по сабжу (будет объект константным или нет
Автор: σ
Дата: 16.08.23
и затем — если он константный, будет ли UB при доступе к нему на запись после конструирования)?


R>Помочь может очень легко: мы имеем полное право отвечать на эти вопросы в презумции, что NRVO не примененяется (полагаю, ответы очевидны), а применение NRVO, если таковое произошло, никак не должно повлиять на рассуждения и выводы.


Ну ок, пусть будет так. Я же останусь при мнении что нельзя считать что "NRVO не примененяется а если применяется то это не влияет на ...", так как в случае применения NRVO существуют явно наблюдаемая разница в поведении программы:
— выбрасываются побочные эффекты в конструкторе так как выбрасывается весь конструктор,
— this объекта будет одинаковый внутри функции и снаружи,
— объект будет один а не два (со всеми вытекающими)
Re[105]: Че ты лыбишься, хам трамвайный?
От: rg45 СССР  
Дата: 22.08.23 16:11
Оценка: :)
Ты хочешь сказать, что программа из well-defined может превратиться в ill-formed от простого изменения уровня оптимизации? Ты с головой дружишь вообще?
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 22.08.2023 16:33 rg45 . Предыдущая версия .
Re[105]: Когда это наконец станет defined behavior?
От: σ  
Дата: 22.08.23 16:13
Оценка: -1 :)
V>>именно так, для программиста этот исход не определен заранее. Аналогично программист не знает заранее, проинлайнит ли компилятор функцию или нет. Я с этим полностью согласен, это можно называть некоей "оптимизацией". Вопрос в другом: как это утверждение может помочь по сабжу (будет объект константным или нет
Автор: σ
Дата: 16.08.23
и затем — если он константный, будет ли UB при доступе к нему на запись после конструирования)?


R>Помочь может очень легко: мы имеем полное право отвечать на эти вопросы в презумции, что NRVO не примененяется (полагаю, ответы очевидны), а применение NRVO, если таковое произошло, никак не должно повлиять на рассуждения и выводы.


А если взять что-нибудь типа
bool nrvo_didnt_happen;

struct S {
  S() = default;
  S(S&) { nrvo_didnt_happen = true; }
  S(S&&) { nrvo_didnt_happen = true; }
};
    
S f()
{
    S s;
    return s;
}

#include <iostream>

int main()
{
    S s = f();

    std::cout << nrvo_didnt_happen << '\n';
}

И спросить про вывод программы, ответ тоже будет
> мы имеем полное право отвечать на эти вопросы в презумции, что NRVO не примененяется, а применение NRVO, если таковое произошло, никак не должно повлиять на рассуждения и выводы.
?
Re[106]: Когда это наконец станет defined behavior?
От: B0FEE664  
Дата: 22.08.23 16:16
Оценка:
Здравствуйте, σ, Вы писали:

BFE>>

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class
σ>object, even if the constructor selected for the copy/move operation and/or the destructor for the object
σ>have side effects. In such cases, the implementation treats the source and target of the omitted copy/move
σ>operation as simply two different ways of referring to the same object.


BFE>>Тут говорится, что реализация работает двумя различными путями с двумя объектами как с одним и тем же объектом. Здесь не утверждается, что объект один. Объектов два: "source and target".

σ>С чего ты решил, что source and target это объекты, а не (glvalue-)выражения или переменные?

Это следует из первого предложения:

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects.

Речь идёт про объект.

σ>Дальше про source и target написано, что это «ways of referring to the same object».

σ>Что, скорее, является way of referring to an object: переменная/выражение или объект? Переменную или выражение вполне можно обозвать "способом ссылаться на объект". А называть объект "способом ссылаться на объект"? Ну ХЗ…
Ага. Nice copium, как вы говорите: как хочешь, так и понимай.

A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable’s name, if any, denotes the reference or object.

Переменная, она не "referring to", она "denotes". Ну, это если формально подходить.

Я согласен, что source и target могут рассматриваться как переменные, но каждая переменная, если она не ссылка, декларирует свой объект. => два объекта.

BFE>> То, что эти операции опускаются, не означает, что объект один — формально объектов два

σ>Формально объект один, формально по-прежнему два способа на него ссылаться. Которые теперь ссылаются на один и тот же объект.
Нет, объектов два. Как вы себе представляете вызов конструктора копирования для самого себя? так: T t = t;? Уверяю вас, здесь речь не про этот случай. Речь идёт про конструктор копирования. Это когда один объект копируют в другой. Невозможно "omit" то, что не вызывается.

  Скрытый текст
BFE>>
σ>std::map<int, int> buildMap()
σ>{
σ>    std::map<int, int> result; // создали неконстантный объект result, после выполнения конструктора началось время жизни объекта result
σ>    result.insert(42, 43);     // изменили неконстантный объект result
σ>    return result;             // скопировали неконстантный объект result в возвращаемый неконстантный объект (*) - это операция пропускается
σ>                               //   после завершения конструктора временного объекта началось время жизни возвращаемого неконстантного объекта несмотря на то, что операция копирования была пропущена.
σ>                               // перед вызовом деструктора объекта result заканчивается время жизни объекта result
σ>                               // разрушили неконстантный объект result (*) - это операция пропускается
σ>}
σ>const std::map<int, int> someDictionary = buildMap(); // возвращаемый функцией buildMap() неконстантный объект передаётся в конструктор класса map             (*) - это операция пропускается 
σ>                                                      // внутри конструктора возвращаемый функцией buildMap() неконстантный объект перемещается (копируется)   (*) - это операция пропускается
σ>                                                      // после завершения выполнения конструктора                                                              (*) - это операция пропускается 
σ>                                                      //   началось время жизни константного объекта обозначаемого переменной someDictionary 
σ>                                                      // время жизни возвращаемого функцией buildMap() неконстантного объекта окончено  
σ>                                                      // после выполнения выражения возвращаемый функцией buildMap() неконстантный объект разрушается          (*) - это операция пропускается 
σ>

BFE>>- вот так (без подробностей) может выглядеть выполнение на абстрактной машине. Как видите время жизни константного объекта обозначаемого переменной someDictionary начинается после создания и модификации объекта.

σ>Ну ок, теперь я. Буду идти по sequenced before control flow-а. (Подразумевается C++17+, так что временных объектов нет в принципе, а не потому что copy elision)

σ>Встречаем definition const std::map<int, int> someDictionary ….

σ>Стандарт говорит в [intro.object]/1 «An object is created by a definition» и «The properties of an object are determined when the object is created», а в [basic.type.qualifier]/1 «The type of an object includes the cv-qualifiers specified in the decl-specifier-seq… when the object is created».
σ>decl-specifier-seq здесь это const std::map<int, int>, так что тип объекта const std::map<int, int> (ну, по крайней мере, тип точно включает в себя const, согласно цитате).

До вызова buildMap объект ещё не создан, а значит и свойства его ещё не определены.

σ>Дальше вызывается функция buildMap, где встречаем ещё один definition: std::map<int, int> result. Как описано выше, создаётся объект и назначаются его свойства, в частности, тип std::map<int, int>.

А ещё свойство lifetime.

σ>Когда у нас NRVO, мы второй раз определяем ему свойства одного и того же объекта, убрая const-квалификатор.

Вы уверены, что const — это свойство?

σ>Дальше надо решать, после которой инициализации мы начинаем лайфтайм. Допустим, после первой (закончившейся), для result.

Свою точку зрения на начало/конец лайфтайм я уже расписал.

σ>Ну а дальше объект так и остаётся с типом без const-квалификатора, т.к. его properties больше не determine ¯\_(ツ)_/¯

Ну т.е. его можно менять, как я рядом написал?
И каждый день — без права на ошибку...
Re[106]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 22.08.23 16:18
Оценка:
Здравствуйте, σ, Вы писали:

σ>И спросить про вывод программы, ответ тоже будет

>> мы имеем полное право отвечать на эти вопросы в презумции, что NRVO не примененяется, а применение NRVO, если таковое произошло, никак не должно повлиять на рассуждения и выводы.
σ>?

А не пойти бы тебе куда подальше, вместе со своей демагогией? Разница на побочных эффектах существует на законных основаниях, ты сам прекрасно это знаешь, и это никак не порождает UB.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 22.08.2023 16:19 rg45 . Предыдущая версия .
Re[112]: Когда это наконец станет defined behavior?
От: B0FEE664  
Дата: 22.08.23 16:28
Оценка:
Здравствуйте, vopl, Вы писали:

BFE>>someDictionary вообще не начинает жить, а вот result — живёт

V>Не забываем что someDictionary/result — это лишь имена, у них нет lifetime, они не живут.
someDictionary обозначает объект, который жить не начинал и он refering to объект result, который не константный. А значит const должен игнорироваться и объект можно менять.

V> Lifetime есть только у объекта, который the same и доступен по обоим этим именам. Объект живет. Таким образом, наблюдаемый lifetime у the same object один и тот же независимо через какое имя мы смотрим на объект.

Ага. Только вот объект создан неконстантным, а значит его можно менять через переменную someDictionary (в предположении, что const — это свойство).

Вы всё ещё не чувствуете, что это сведение к абсурду? Нет? Настаиваете, что это один и тот же объект?
И каждый день — без права на ошибку...
Re[106]: Че ты лыбишься, хам трамвайный?
От: σ  
Дата: 22.08.23 16:43
Оценка: +1 -1
R>Ты хочешь сказать, что программа из well-defined может превратиться в ill-formed

ill-formed с UB спутал?

R>от простого изменения уровня оптимизации? Ты с головой дружишь вообще?


Ой...
Или здесь тоже законные основания побочных эффектов?
Re[113]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 22.08.23 16:50
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, vopl, Вы писали:


BFE>>>someDictionary вообще не начинает жить, а вот result — живёт

V>>Не забываем что someDictionary/result — это лишь имена, у них нет lifetime, они не живут.
BFE>someDictionary обозначает объект, который жить не начинал и он refering to объект result, который не константный. А значит const должен игнорироваться и объект можно менять.

ну хз, звучит стремно
someDictionary обозначает объект, который ... refering to объект result. То есть, получается объект ссылается на объект. Тут не могу согласиться никак.

V>> Lifetime есть только у объекта, который the same и доступен по обоим этим именам. Объект живет. Таким образом, наблюдаемый lifetime у the same object один и тот же независимо через какое имя мы смотрим на объект.

BFE>Ага. Только вот объект создан неконстантным

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

BFE>, а значит его можно менять через переменную someDictionary (в предположении, что const — это свойство


по моим данным, "const" это часть свойства "тип" объекта, то есть, я бы ыполне употреблял выражение что const — это свойство объекта

BFE>).


BFE>Вы всё ещё не чувствуете, что это сведение к абсурду? Нет? Настаиваете, что это один и тот же объект?


Настаиваю что по формулировкам стандарта — это один объект. Чуствую что скоро будет иметь место какой нибудь дефект-репорт, типа "NRVO makes an object type collision ...blabla"
Re[114]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 22.08.23 16:57
Оценка:
Здравствуйте, vopl, Вы писали:

V>по стандарту объект создается того типа который был при его декларации, а деклараций две, это явная коллизия, зря мы тут копья ломаем


вот кстати, а эта хрень c the same object — она же нарушает ODR, так как объект один (если мы принимаем что он один) а определения два (в двух объявлениях) и они разные
Re[115]: Когда это наконец станет defined behavior?
От: σ  
Дата: 22.08.23 17:13
Оценка:
V>вот кстати, а эта хрень c the same object — она же нарушает ODR



ODR — это про переменные/типы/функции, ихние шаблоны и т.п., а не про объекты
Re[116]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 22.08.23 17:18
Оценка:
Здравствуйте, σ, Вы писали:

V>>вот кстати, а эта хрень c the same object — она же нарушает ODR


σ>


σ>ODR — это про переменные/типы/функции, ихние шаблоны и т.п., а не про объекты


ну так наш объект это ж и есть переменная, разве нет? https://timsong-cpp.github.io/cppwp/basic.pre#6
Re[115]: Когда это наконец станет defined behavior?
От: B0FEE664  
Дата: 22.08.23 17:20
Оценка: +1
Здравствуйте, vopl, Вы писали:

V>>по стандарту объект создается того типа который был при его декларации, а деклараций две, это явная коллизия, зря мы тут копья ломаем

V>вот кстати, а эта хрень c the same object — она же нарушает ODR, так как объект один (если мы принимаем что он один) а определения два (в двух объявлениях) и они разные

Ещё один аргумент за то, что это два объекта, которые рассматриваются как один.
И каждый день — без права на ошибку...
Re[117]: Когда это наконец станет defined behavior?
От: σ  
Дата: 22.08.23 17:28
Оценка: +1
V>ну так наш объект это ж и есть переменная, разве нет?



Переменная это такая, как бы сказать, синтаксическая конструкция.
А объект — «рантайм»-штука. Ну, кроме как в константных выражениях, которые, как бы, компайл-тайм.

Переменная — всегда одна. А объектов, ассоциированных с ней, от 0 до бесконечности. В каждом, назовём так, контексте — свой.

V>https://timsong-cpp.github.io/cppwp/basic.pre#6


Это… надо уметь читать. Ну или переписать так, чтобы было понятно всем. Но переписывать отдельно не хотят.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.