Этот код имеет неопределенное поведение:
#include <string>
std::string make_str(const char* s)
{
return s;
}
const char* get_str(const std::string& s)
{
return s.c_str();
}
const char* bad()
{
return get_str(make_str("hello"));
}
Плохая функция создает временный std :: string и возвращает указатель на свои данные, который становится недействительным, как только функция вернулась.
GCC 5+ ловит это («функция возвращает адрес локальной переменной»), но только если компилируется с -O3
.При более типичных уровнях оптимизации, включая -O2
, GCC компилирует его без жалоб, даже с -Wall -Wextra
.Clang никогда не поймает его, если вы не используете экспериментальную функцию -Wlifetime
.
Мой вопрос: Можем ли мы явно сообщить компилятору о таких зависимостях времени жизни, например, используя атрибут?Например, я хотел бы иметь возможность сделать это:
[[lifetime-depends : s]] // hypothetical syntax
const char* get_str(const std::string& s);
Или, может быть, так:
const char* get_str(const std::string& s)
__attribute__((lifetime-depends(0))); // hypothetical syntax
Я приму ответ, который работает с любым официальным выпуском GCC илиЗвон, но предпочитаю GCC 6.1 с C ++ 14.Эксперимент Кланга -Wlifetime
не является ответом, потому что я хочу быть явным, а не полагаться на эвристику (которая, по-видимому, в любом случае не будет работать на нескольких единицах перевода).
В качестве альтернативы я приму ответ, предоставляющийпричины, по которым это было бы бесполезно или практически невозможно реализовать.