Здравствуйте, vopl, Вы писали:
V>someDictionary обозначает объект, который ... refering to объект result. То есть, получается объект ссылается на объект. Тут не могу согласиться никак.
Так в стандарте так пишут.
V>по стандарту объект создается того типа который был при его декларации, а деклараций две, это явная коллизия, зря мы тут копья ломаем
По стандарту создаётся два объекта. По стандарту, в некоторых случаях, для двух объектов может быть проведена такая оптимизация вызовов деструкторов и конструкторов, что эти два объекта будут выглядеть как один.
V>Настаиваю что по формулировкам стандарта — это один объект. Чуствую что скоро будет иметь место какой нибудь дефект-репорт, типа "NRVO makes an object type collision ...blabla"
Не, ну вы серьёзно?
Это же классическая разница между "быть" и "выглядеть".
Вот здесь:
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.
treats as — это "рассматривать как", "обрабатывать как", "трактовать как", но не "быть" и не "являться".
И каждый день — без права на ошибку...
Re[118]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
V>>ну так наш объект это ж и есть переменная, разве нет?
σ>
σ>Переменная это такая, как бы сказать, синтаксическая конструкция. σ>А объект — «рантайм»-штука. Ну, кроме как в константных выражениях, которые, как бы, компайл-тайм.
σ>Переменная — всегда одна. А объектов, ассоциированных с ней, от 0 до бесконечности. В каждом, назовём так, контексте — свой.
судя по всему следует читать так: переменная вводится декларацией, у нас декларации две, сделовательно переменных две. То есть, это две разные переменные.
Re[115]: Когда это наконец станет defined behavior?
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, vopl, Вы писали:
V>>someDictionary обозначает объект, который ... refering to объект result. То есть, получается объект ссылается на объект. Тут не могу согласиться никак. BFE>Так в стандарте так пишут.
где?
V>>Настаиваю что по формулировкам стандарта — это один объект. Чуствую что скоро будет иметь место какой нибудь дефект-репорт, типа "NRVO makes an object type collision ...blabla" BFE>Не, ну вы серьёзно?
ага
BFE>Это же классическая разница между "быть" и "выглядеть". BFE>Вот здесь: BFE>
BFE>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>treats as — это "рассматривать как", "обрабатывать как", "трактовать как", но не "быть" и не "являться".
все эти "трактовать как" относятся к source and target, а не к объекту. Либо я не понял суть момента
Re[106]: Когда это наконец станет defined behavior?
Специально для троллей-демагогов, склонных читать стандарт, не понимая значения слов в зависимости от контекста, я принёс UB покруче:
#include <stdio.h>
#include <stdlib.h>
struct T { int i; };
void foo(const int* i, struct T* t) {
int i1 = *i;
printf("i1=%i\n", i1);
*t = {42};
int i2 = *i;
printf("i2=%i\n", i2);
}
int main() {
struct T t {1337};
foo(&t.i, &t);
return 0;
}
Одна и та же область памяти одновременно занята и типом int, и типом struct T! Это же нарушение правила strict aliasing!!! И пусть все компиляторы даже с -O3 читают значение по адресу i дважды, но это же на самом деле UB!!! Я высрал такой вывод, прочитав стандарт и поняв его по-своему!!!
А теперь докажите мне, со ссылками на стандарт, что в будущем ни один компилятор не соптимизирует этот код, выкинув второе чтение из памяти. А я буду строить из себя дурачка и тыкать в стандарт с тупым лицом.
Re[105]: Когда это наконец станет defined behavior?
Здравствуйте, rg45, Вы писали:
R>Помочь может очень легко: мы имеем полное право отвечать на эти вопросы в презумпции, что NRVO не примененяется (полагаю, ответы очевидны), а применение NRVO, если таковое произошло, никак не должно повлиять на рассуждения и выводы.
применение NRVO выкидывает даже side эффекты, так что ожидать можно чего угодно.
И каждый день — без права на ошибку...
Re[106]: Когда это наконец станет defined behavior?
σ>И спросить про вывод программы, ответ тоже будет >> мы имеем полное право отвечать на эти вопросы в презумции, что NRVO не примененяется, а применение NRVO, если таковое произошло, никак не должно повлиять на рассуждения и выводы. σ>?
Это пример не интересный, его надо усложнить добавив вызовов f():
int main()
{
nrvo_didnt_happen = false;
S s1 = f();
std::cout << nrvo_didnt_happen;
nrvo_didnt_happen = false;
S s2 = f();
std::cout << nrvo_didnt_happen;
nrvo_didnt_happen = false;
S s3 = f();
std::cout << nrvo_didnt_happen;
}
Если вы думает, что стандарт гарантирует вывод 111 или 000, то вы ошибаетесь. Могут быть все 8 вариантов 000, 001, 010, 011, ... 111
Здравствуйте, vopl, Вы писали:
V>>>someDictionary обозначает объект, который ... refering to объект result. То есть, получается объект ссылается на объект. Тут не могу согласиться никак. BFE>>Так в стандарте так пишут. V>где?
The variable’s name, if any, denotes the reference or object.
И, если source and target — имена переменных, как меня путаются убедить, то "referring to":
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>>Не, ну вы серьёзно? V>ага
Без меня.
BFE>>Это же классическая разница между "быть" и "выглядеть". BFE>>Вот здесь: BFE>>
BFE>>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>>treats as — это "рассматривать как", "обрабатывать как", "трактовать как", но не "быть" и не "являться".
V>все эти "трактовать как" относятся к source and target, а не к объекту. Либо я не понял суть момента
Да, к source and target. И эти source and target "трактуются как" два пути к одному и тому же объекту, а на самом деле это два пути, к двум разным объектам и операция копирования из одного объекта в другой выброшена.
σ>>С чего ты решил, что source and target это объекты, а не (glvalue-)выражения или переменные? BFE>Это следует из первого предложения: 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.
BFE>Речь идёт про объект.
Причём, про один. Значит, из первого предложения следует, что объект один.
Столько же логики, как в том, что из первого предложения следует, что source и target — это объект. (Примерно ноль.)
σ>>Дальше про source и target написано, что это «ways of referring to the same object». σ>>Что, скорее, является way of referring to an object: переменная/выражение или объект? Переменную или выражение вполне можно обозвать "способом ссылаться на объект". А называть объект "способом ссылаться на объект"? Ну ХЗ… BFE>Ага. Nice copium, как вы говорите: как хочешь, так и понимай.
Copium — это делать вид, что "объект это способ ссылаться на объект" нормальное словоупотребление.
BFE>
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.
BFE>Переменная, она не "referring to", она "denotes". Ну, это если формально подходить.
Если формально подходить, denotes курсивом не выделено, т.е. это не термин, а обычное слово. И вместо него могут использоваться (и используются, искать влом) синонимы. "referring to", "names" — вполне себе (контекстуальные) синонимы для "denotes". (Нет, мне не нравится ни одно из этих слов, я бы ввёл термин, но это уже оффтоп)
BFE>>> То, что эти операции опускаются, не означает, что объект один — формально объектов два σ>>Формально объект один, формально по-прежнему два способа на него ссылаться. Которые теперь ссылаются на один и тот же объект. BFE> Нет, объектов два. Как вы себе представляете вызов конструктора копирования для самого себя? так: T t = t;? Уверяю вас, здесь речь не про этот случай. Речь идёт про конструктор копирования. Это когда один объект копируют в другой. Невозможно "omit" то, что не вызывается.
Есть два экземпляра абстрактной машины (точнее, два возможных выполнения): в одном NRVO применяется, в другом — нет.
Во второй вызывается конструктор копирования. В первой — нет. Получается "omit" по сравнению со второй.
σ>>Ну ок, теперь я. Буду идти по 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, согласно цитате).
BFE>До вызова buildMap объект ещё не создан, а значит и свойства его ещё не определены.
Что скажешь про void* p = &p;? До после ; тоже объект ещё не создан? И что тогда можно сказать про &p?
σ>>Дальше вызывается функция buildMap, где встречаем ещё один definition: std::map<int, int> result. Как описано выше, создаётся объект и назначаются его свойства, в частности, тип std::map<int, int>. BFE>А ещё свойство lifetime.
А что с ним такого особенного? До начала lifetime объект… вне lifetime. Что тут обсуждать?
σ>>Когда у нас NRVO, мы второй раз определяем ему свойства одного и того же объекта, убрая const-квалификатор. BFE>Вы уверены, что const — это свойство?
Ой-вей. Тип объекта это его свойство. Я думал будет понятно, какие слова были опущены. На всякий случай: > мы второй раз определяем ему свойства одного и того же объекта, убрая const-квалификатор из его типа.
На ещё всякий случай: это я так описал смену типа с const map<> на map<>
σ>>Ну а дальше объект так и остаётся с типом без const-квалификатора, т.к. его properties больше не determine ¯\_(ツ)_/¯ BFE>Ну т.е. его можно менять, как я рядом написал?
Про то, что если объект неконстантный, то его можно менять и вне функции я писал ещё в https://rsdn.org/forum/cpp/8583578.1
BFE>Могут быть все 8 вариантов 000, 001, 010, 011, ... 111
Для этого в [class.copy.elision] должно присутствовать кое-какое слово, которого там нет. Ты заметил это?
Скрытый текст
Я бы сказал, это дефект
Re[108]: Когда это наконец станет defined behavior?
Здравствуйте, σ, Вы писали:
σ>Для этого в [class.copy.elision] должно присутствовать кое-какое слово, которого там нет. Ты заметил это? σ>Я бы сказал, это дефект
Здравствуйте, rg45, Вы писали:
σ>>Для этого в [class.copy.elision] должно присутствовать кое-какое слово, которого там нет. Ты заметил это? σ>>Я бы сказал, это дефект
R>А если это дефект, тогда к чему была эта
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, σ, Вы писали:
R>>>Ты хочешь сказать, что программа из well-defined может превратиться в ill-formed
σ>>ill-formed с UB спутал?
R>ill-formed программа не обязательно порождает UB, но программа, порождающая UB — обязательно ill-formed. Иди логику учи, дядя.
cppreference.com считает что
1. ill-formed в этом случае нужно обязательно брать с пометкой no diagnostic required, и такая штука существенно отличается от просто ill-formed (который явно диагностирует проблему)
2. причинность ровно наоборот, не "UB -> ill-formed, no diagnostic required", а "ill-formed, no diagnostic required -> UB". То есть, во множестве UB есть такие, которые не являются "ill-formed, no diagnostic required"
Здравствуйте, vopl, Вы писали:
V>cppreference.com считает что V>1. ill-formed в этом случае нужно обязательно брать с пометкой no diagnostic required, и такая штука существенно отличается от просто ill-formed (который явно диагностирует проблему)
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, vopl, Вы писали:
V>>>>someDictionary обозначает объект, который ... refering to объект result. То есть, получается объект ссылается на объект. Тут не могу согласиться никак. BFE>>>Так в стандарте так пишут. V>>где? BFE>
BFE>The variable’s name, if any, denotes the reference or object.
BFE>И, если source and target — имена переменных, как меня путаются убедить, то "referring to": BFE>
BFE>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.
то есть,
source is a variable name, source referring to the object
target is a variable name, target referring to the same object
и нигде нет такого что "объект ссылается на объект"
BFE>>>Не, ну вы серьёзно? V>>ага BFE>Без меня.
BFE>>>Это же классическая разница между "быть" и "выглядеть". BFE>>>Вот здесь: BFE>>>
BFE>>>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>>>treats as — это "рассматривать как", "обрабатывать как", "трактовать как", но не "быть" и не "являться".
V>>все эти "трактовать как" относятся к source and target, а не к объекту. Либо я не понял суть момента BFE>Да, к source and target. И эти source and target "трактуются как" два пути к одному и тому же объекту, а на самом деле это два пути, к двум разным объектам и операция копирования из одного объекта в другой выброшена.
Услышал. Ну, не знаю. Субъективно все это. Лично мне кажется что логику надо применять такую
1. выдавливается копирование
2. после того как оно выдавлено — теряет смысл наличие двух объектов, соответственно выдавливается эта двойственность
3. остается просто один объект
ну, опять же, это уже область сугубо субъективного, никаких доводов в пользу моей трактовки у меня нет
считаю вопрос исчерпаным, с формулировкой "не договорились"
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, vopl, Вы писали:
V>>cppreference.com считает что V>>1. ill-formed в этом случае нужно обязательно брать с пометкой no diagnostic required, и такая штука существенно отличается от просто ill-formed (который явно диагностирует проблему)
R>А стандарт языка говорит, что
R>https://timsong-cpp.github.io/cppwp/intro.defs#defns.ill.formed
R>
R>3.25
R>ill-formed program
R>program that is not well-formed
по определению, well-formed программа всего лишь
1. не нарушает синтаксис
2. не нарушает правила семантики
для того чтобы увязать это с неопределенным поведением — надо проделать еще какие то шаги, одного только представленного определения не достаточно, так как в нем нет ни слова о неопределенном поведении