Clang 3.9 чрезвычайно многократно использует память, используемую временными.Обнаружение оборванных ссылок на временные
Этот код UB (упрощенный код):
template <class T>
class my_optional
{
public:
bool has{ false };
T value;
const T& get_or_default(const T& def)
{
return has ? value : def;
}
};
void use(const std::string& s)
{
// ...
}
int main()
{
my_optional<std::string> m;
// ...
const std::string& s = m.get_or_default("default value");
use(s); // s is dangling if default returned
}
У нас есть тонны кода что-то, как и выше (my_optional
всего лишь простой пример для иллюстрации).
Из-за UB все компиляторы clang с 3.9 начинают повторное использование этой памяти, и это законное поведение.
Вопрос: как обнаружить такие обвисшие ссылки во время компиляции или что-то вроде дезинфицирующего средства во время выполнения? Никакой дезинфицирующее средство для клещей не может их обнаружить.
Обновление. Пожалуйста, не отвечайте: «используйте std::optional
». Читайте внимательно: вопрос НЕ об этом.
Upd2. Пожалуйста, не отвечайте: «ваш код плохой». Читайте внимательно: вопрос НЕ о дизайне кода.
@Someprogrammerdude Спасибо, я знаю. Дело в том, что нет константы, но 'std :: string (« значение по умолчанию »)' построено неявно, это временно, и оно умирает после этой строки. Так '' 'на следующей строке свисает. – vladon
№ Строка * временно * объект _dies_ в конце строки. Ссылка на него висит на строке 'use (s)'. – vladon
@Someprogrammerdude "временная привязка к эталонному параметру в вызове функции существует до конца полного выражения, содержащего вызов этой функции: если функция возвращает ссылку, которая пережитёт полного выражения, она становится оборванной ссылкой" http://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary – vladon