Здравствуйте, Alekzander, Вы писали:
S>>Есть персонажи, которые считают, что их мнение единственно правильное, но когда с ними пытаешься общаться как со взрослыми людьми, они ведут себя как обиженные на весь мир и избалованные маленькие дети.
A>Поэтому я обычно и не общаюсь с C++ комьюнити
Обиженка говорит что не общается с C++ комьюнити в одном из чатов C++ комьюнити.
Re[10]: Не могу найти пример бага, который я не понял
Здравствуйте, so5team, Вы писали:
S>>>Есть персонажи, которые считают, что их мнение единственно правильное, но когда с ними пытаешься общаться как со взрослыми людьми, они ведут себя как обиженные на весь мир и избалованные маленькие дети.
A>>Поэтому я обычно и не общаюсь с C++ комьюнити
S>Обиженка говорит что не общается с C++ комьюнити в одном из чатов C++ комьюнити.
Ой вей.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re[5]: Не могу найти пример бага, который я не понял
Здравствуйте, Alekzander, Вы писали:
A>с чего вообще начинались ссылки и константность? С того, что они (конечно же, в отличие от ортодоксальных указателей!) делают мир БЕЗОПАСНЕЕ.
Боюсь, никакая новая сущность не может сдвинуть мир в сторону безопасности по всем направлениям. По каким-то всегда возникнут другие опасности, этого не избежать.
A>я лучше отчекаю тысячу указателей в ручном режиме, чем буду искать одну вот такую заподлянку.
Эта "заподлянка" мало чем отличается от указателя на константный объект, который так же может и измениться, и стать недействительным в течение времени существования указателя. От указателей тоже откажетесь?
Re[6]: Не могу найти пример бага, который я не понял
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Эта "заподлянка" мало чем отличается от указателя
Указатель это указатель, а не абстракция адреса, которая пытается выглядеть как тип, но не гарантирует той же безопасности, что работа с типом. Другими словами, указатель является опасной штукой, но он и выглядит опасно, в отличие от.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re[7]: Не могу найти пример бага, который я не понял
Здравствуйте, Alekzander, Вы писали:
A>указатель является опасной штукой, но он и выглядит опасно, в отличие от.
Что "выглядит опаснее" — автомобиль или самолет? А если сравнить по количеству травм/смертей на пассажиро-километр?
Я, за примерно тридцать лет активного пользования константными ссылками, ни разу не нарывался на обсуждаемую проблему. Мне действительно стоило все это время воздерживаться от использования ссылок?
Re[8]: Не могу найти пример бага, который я не понял
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Я, за примерно тридцать лет активного пользования константными ссылками, ни разу не нарывался на обсуждаемую проблему. Мне действительно стоило все это время воздерживаться от использования ссылок?
Не знаю, тебе виднее. Я сам ими пользуюсь, раз уж это мейнстрим (везде, где это оправдано — т.е. не в сишных апях и тому подобных местах). Но ситуация, которую иллюстрирует этот пример, довольно упячная.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re[9]: Не могу найти пример бага, который я не понял
Здравствуйте, Alekzander, Вы писали:
A>Но ситуация, которую иллюстрирует этот пример, довольно упячная.
Думаю, если порыться в сборниках курьезов, то можно найти и менее очевидные засады, в том числе и с более часто применяемыми средствами языка. И что тогда делать с этими средствами?
Re[4]: Не могу найти пример бага, который я не понял
Здравствуйте, so5team, Вы писали:
S>Начиная с C++11 от этого можно попробовать защититься запретив конструктор, который принимает rvalue references. Что и было показано в том примере.
S>Но это же C++, здесь на каждую хитрую задницу тут же отыскивается болт с нужной резьбой. В данном случае это вариант шаблона функции std::min от двух аргументов. Этот вариант принимает аргументы по константной ссылке и возвращает так же константную ссылку. При этом если в std::min передать временные объекты, то std::min примет их по константной ссылке и точно так же вернет константную ссылку на один из временных объектов. Со вполне предсказуемым протуханием этой ссылки после завершения выражения, в котором std::min был вызван. Что и позволяет отдать в Data ссылку, которая протухнет сразу же после завершения работы конструктора.
Потому что в стандартной библиотеке есть недоделка.
Здравствуйте, so5team, Вы писали:
S>Начиная с C++11 от этого можно попробовать защититься запретив конструктор, который принимает rvalue references. Что и было показано в том примере.
Ключевое слово — "попробовать".
К сожалению, есть огромное количество способов протухлить ссылки. Тут всю систему типов менять надо. И получится что-то наподобие раста (и то не факт, что получится нечто совершенное).
Перекуём баги на фичи!
Re[4]: Не могу найти пример бага, который я не понял
Здравствуйте, so5team, Вы писали:
S>Проблема в том, что 42 -- это временный экземпляр типа int, фактически это rvalue (или как оно там по стандарту правильно называется). S>Но ссылка на rvalue в С++ неявным образом преобразуется к const-ссылке, поэтому в Data уходит константная ссылка на временный объект.
Спасибо за разъяснение, но у меня сразу 2 вопроса возникает.
1) Разве константная ссылка не продляет время жизни временного объекта
2) В данном примере почему 42 не попадает под .rodata, оптимизатор?
Re[5]: Не могу найти пример бага, который я не понял
Здравствуйте, Igore, Вы писали:
I>1) Разве константная ссылка не продляет время жизни временного объекта
Продлевается только в одном scope:
{
{
const int &r = 42;
// тут r жива
}
// а тут уже нет
}
I>2) В данном примере почему 42 не попадает под .rodata, оптимизатор?
Значение инта компилятор может подставить инлайн в команду.
Все зависит от того, что с ссылкой делается.
Например, если берется адрес &r и используется, то компилятор должен какой-то адрес выдать, на стеке или в константных данных.
В случае с ссылкой-членом данных и конструктором в объекте неявно указатель будет храниться.
S>struct Data {
S> const int & _i;
S> explicit Data(const int & i) : _i{i} {}
S>};
Т.е. sizeof(Data) == sizeof(int*) и ничем особо протухшего указателя не отличается.
Re[4]: Не могу найти пример бага, который я не понял
Здравствуйте, so5team, Вы писали:
S>Соответственно, как только завершается выражение, в котором конструктор вызывался, временный объект перестает существовать, а ссылка на него протухает.
Да вроде разрешено продлять время жизни захваченного объекта до конца scope.
Т.е., вот так было безопасно писать:
const int & i = 42;
std::cout << i << std::endl;
Re[6]: Не могу найти пример бага, который я не понял
Здравствуйте, vdimas, Вы писали:
S>>Соответственно, как только завершается выражение, в котором конструктор вызывался, временный объект перестает существовать, а ссылка на него протухает.
V>Да вроде разрешено продлять время жизни захваченного объекта до конца scope.
Это не тот случай.
V>Т.е., вот так было безопасно писать: V>
V>const int & i = 42;
V>std::cout << i << std::endl;
V>
Повторюсь, это не тот случай.
Re[7]: Не могу найти пример бага, который я не понял
V>ИМХО, время жизни временного объекта 42 должно быть продлено.
Ну вот вообще не так!
Проблема же в том, что функция min получает ссылки — и возвращает ссылки. А принимающая сторона ничего не знает про время жизни этих возвращённых ссылок, поэтому и продлевать не может.
Нужно написать такую версию min, которая если получает хотя бы один rvalue reference, то должна возвращать rvalue, и пусть принимающая сторона делает copy elision и продлевает жизнь как хочет, на своё усмотрение.