Предупреждение C4172: Возвращение ссылки на const std :: string, связанной с локальной переменной.Насколько это безопасно? - PullRequest
6 голосов
/ 12 августа 2011

Я только строил один из наших проектов на работе, и я вижу, что была добавлена ​​новая функция:

const std::string& ClassName::MethodName() const
{
   return "";
}

Компилятор выдает предупреждение:

Предупреждение C4172: возвратадрес локальной переменной или временный

Я думаю, что компилятор прав. Насколько безопасна эта функция?

Обратите внимание, что функция не возвращает const char*, что было бы в порядке, поскольку строковые литералы имеют статическую длительность хранения.Возвращает ссылку на const std::string

Ответы [ 4 ]

7 голосов
/ 12 августа 2011

Да, это небезопасно.
Возвращение адреса локальной или временной переменной и разыменование его приводит к неопределенному поведению.

Как вы прокомментировали:
Да, время жизни временной привязки кпостоянная ссылка увеличивается до времени жизни постоянной.Но для этого требуется, чтобы вызывающая сторона приняла возвращаемое значение в константной ссылке, поэтому сама функция не будет безопасной.

Из стандарта C ++:
C ++ 03 12.2 Временные объекты:

Второй контекст - это когда ссылка связана с временным объектом.Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом для подобъекта, к которому привязан временный объект , сохраняется в течение времени жизни ссылки , за исключением случаев, указанных ниже ...

Временная привязка к элементу ссылки в ctor-initializer конструктора (12.6.2) сохраняется до выхода из конструктора.Временная привязка к ссылочному параметру в вызове функции (5.2.2) сохраняется до завершения полного выражения, содержащего вызов. Временная привязка к возвращенному значению в операторе возврата функции (6.6.3) сохраняется до выхода из функции

3 голосов
/ 12 августа 2011

То, что вы сделали, на самом деле делает это внутри компилятора:

const std::string* ClassName::MethodName() const
{
   std::string temp = "";
   return &temp;
}

И возвращать ссылки или указатели на локальные переменные - это плохо.

2 голосов
/ 22 августа 2012

Бывают обстоятельства, когда этот код безопасен. См. ПОЛУЧЕНО № 88: Кандидат на «Самый важный const» .

2 голосов
/ 12 августа 2011

Это пример, который прояснил мне ситуацию:

#include <iostream>
using std::cout;
struct A{
   A()   {
      cout << "Ctor\n";
   }
   ~A()   {
      cout << "Dtor\n";
   }
};

const A& f(){
   return A();
}

int main(){
   const A& ref = f();
   cout << "1\n";
   {
      const A& ref1 = A();
      cout << "2\n";
   }
   cout << "3\n";
}

Выходы

Ctor
Dtor
1
Ctor
2
Dtor
3
...