Telegram Group & Telegram Channel
#creepy

Reference Lifetime Extension

Сегодняшнее "стрёмное правило стандарта": если вы инициализируете константную ссылку (const T&) "временным объектом" (скорее всего rvalue), то этот временный объект не уничтожается как ему было положено, а продолжает жить ровно столько, сколько живет ссылка.

Пример в двух строках:
std::string Foo::GetName();
const std::string& name = obj.GetName(); // легально и не сломается


Наверное, самое популярное использование этого правила - дефолтные значения ссылочных аргументов
void foo(const std::string& s = "default_text");


Это правило супер легко сломать - как только вызовете метод у временного объекта (obj.GetName().data()), или если будет сделан неявный каст, и так далее.
Abseil Tip of the Week показывает больше примеров успеха и фейла.

В моем примере наличие этого правила допустило лютый баг:
class A { ... };
class B : public A { ... };

void foo(const A& a) { ... }
void foo(const B& b) {
// ...
foo(static_cast<A>(b));
}

Я сделал неправильный каст, который скопировал объект, а не скастил к базовому классу. Правильный каст - static_cast<const A&>(b).

Выстрел в ногу произошел, когда foo(const A& a) стал сохранять ссылку на a, чтобы потом её переиспользовать. Пока вызывался foo, ссылка была рабочей, а вот потом объект разрушился и ссылка стала висячей. Дебаг занял достаточно много времени...



group-telegram.com/cxx95/23
Create:
Last Update:

#creepy

Reference Lifetime Extension

Сегодняшнее "стрёмное правило стандарта": если вы инициализируете константную ссылку (const T&) "временным объектом" (скорее всего rvalue), то этот временный объект не уничтожается как ему было положено, а продолжает жить ровно столько, сколько живет ссылка.

Пример в двух строках:

std::string Foo::GetName();
const std::string& name = obj.GetName(); // легально и не сломается


Наверное, самое популярное использование этого правила - дефолтные значения ссылочных аргументов
void foo(const std::string& s = "default_text");


Это правило супер легко сломать - как только вызовете метод у временного объекта (obj.GetName().data()), или если будет сделан неявный каст, и так далее.
Abseil Tip of the Week показывает больше примеров успеха и фейла.

В моем примере наличие этого правила допустило лютый баг:
class A { ... };
class B : public A { ... };

void foo(const A& a) { ... }
void foo(const B& b) {
// ...
foo(static_cast<A>(b));
}

Я сделал неправильный каст, который скопировал объект, а не скастил к базовому классу. Правильный каст - static_cast<const A&>(b).

Выстрел в ногу произошел, когда foo(const A& a) стал сохранять ссылку на a, чтобы потом её переиспользовать. Пока вызывался foo, ссылка была рабочей, а вот потом объект разрушился и ссылка стала висячей. Дебаг занял достаточно много времени...

BY C++95


Warning: Undefined variable $i in /var/www/group-telegram/post.php on line 260

Share with your friend now:
group-telegram.com/cxx95/23

View MORE
Open in Telegram


Telegram | DID YOU KNOW?

Date: |

The Securities and Exchange Board of India (Sebi) had carried out a similar exercise in 2017 in a matter related to circulation of messages through WhatsApp. What distinguishes the app from competitors is its use of what's known as channels: Public or private feeds of photos and videos that can be set up by one person or an organization. The channels have become popular with on-the-ground journalists, aid workers and Ukrainian President Volodymyr Zelenskyy, who broadcasts on a Telegram channel. The channels can be followed by an unlimited number of people. Unlike Facebook, Twitter and other popular social networks, there is no advertising on Telegram and the flow of information is not driven by an algorithm. Just days after Russia invaded Ukraine, Durov wrote that Telegram was "increasingly becoming a source of unverified information," and he worried about the app being used to "incite ethnic hatred." In 2018, Russia banned Telegram although it reversed the prohibition two years later.
from sg


Telegram C++95
FROM American