Я видел другие сообщения об этом, но я все еще немного смущен этим.
const std::string& func(std::string&& ref) { return ref; }
int main(void) {
const std::string& r=func("E");
std::cout << r << std::endl;
}
Технически это должен быть UB, я возвращаю ссылку на "E", которая должна быть уничтожена после выполнения выражения, присваивающего r, верно? Однако никаких предупреждений от clang или g++, возможно, я что-то упускаю?
const std::string& func(std::string ref) { return ref; }
int main(void) {
const std::string& r=func("E");
std::cout << r << std::endl;
}
Clang предупредит о чем-то подобном. Но об этом не предупреждает:
const std::string& func(std::string ref) { return std::move(ref); }
int main(void) {
const std::string& r=func("E");
std::cout << r << std::endl;
}
Он также не предупреждает о чем-то вроде:
std::string&& func(std::string&& ref) { return std::move(ref); }
int main(void) {
std::string&& r=func("E");
std::cout << r << std::endl;
}
Это ведь не УБ?
Если кто-то может прояснить эти вопросы, буду признателен.
@0RR Последний тоже UB.
Итак... немного лишнего, но в каком случае законно возвращать ссылки rvalue?
@pol Вы можете вернуть ссылку rvalue, если знаете, что объект, на который делается ссылка, все еще жив. Или если вы используете его в неоцененном контексте. std::declval приходит на ум.





Однако никаких предупреждений от clang или g++, возможно, я что-то упускаю?
Единственное, что вы упускаете, это тот факт, что компиляторы не гарантируют и не обязаны предупреждать о неопределенном поведении и, как правило, не могут этого делать.
Это ведь не УБ?
Поведение программы не определено. Отсутствие предупреждения не является доказательством четко определенного поведения.
Что бы это ни стоило, и GCC, и Clang обнаруживают эту ошибку во время выполнения с помощью AddressSanitizer.
Спасибо, я немного волновался, что что-то упустил. Я знаю, что не стоит определять, является ли что-то UB или нет, основываясь на поведении компилятора, я подумал, что, возможно, он делает что-то еще.
Тот факт, что программа будет иметь очевидное неопределенное поведение для человека, не налагает на компилятор никаких обязательств. Если он может понять это и предупредить вас об этом, отлично. Если нет, то это печально.