CXX95 Telegram 23
#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, ссылка была рабочей, а вот потом объект разрушился и ссылка стала висячей. Дебаг занял достаточно много времени...
🔥5🤯2



tgoop.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


Share with your friend now:
tgoop.com/cxx95/23

View MORE
Open in Telegram


Telegram News

Date: |

Telegram channels enable users to broadcast messages to multiple users simultaneously. Like on social media, users need to subscribe to your channel to get access to your content published by one or more administrators. With the sharp downturn in the crypto market, yelling has become a coping mechanism for many crypto traders. This screaming therapy became popular after the surge of Goblintown Ethereum NFTs at the end of May or early June. Here, holders made incoherent groaning sounds in late-night Twitter spaces. They also role-played as urine-loving Goblin creatures. Clear Your posting frequency depends on the topic of your channel. If you have a news channel, it’s OK to publish new content every day (or even every hour). For other industries, stick with 2-3 large posts a week. The imprisonment came as Telegram said it was "surprised" by claims that privacy commissioner Ada Chung Lai-ling is seeking to block the messaging app due to doxxing content targeting police and politicians.
from us


Telegram C++95
FROM American