Если вы возвращаете указатель / ссылку на локальную внутреннюю функцию, поведение четко определено , если вы не разыменовываете указатель / ссылку, возвращенные функцией.
Это неопределенное поведение, только когда кто-то отменяет возвращаемый указатель.
Является ли это неопределенным поведением или нет, зависит от кода, вызывающего функцию, а не от самой функции.
Так что, просто во время компиляции функции компилятор не может определить, является ли поведение неопределенным или хорошо определенным. Лучшее, что он может сделать, это предупредить вас о потенциальной проблеме, и это действительно так!
Пример кода:
#include <iostream>
struct A
{
int m_i;
A():m_i(10)
{
}
};
A& foo()
{
A a;
a.m_i = 20;
return a;
}
int main()
{
foo(); //This is not an Undefined Behavior, return value was never used.
A ref = foo(); //Still not an Undefined Behavior, return value not yet used.
std::cout<<ref.m_i; //Undefined Behavior, returned value is used.
return 0;
}
Ссылка на стандарт C ++:
раздел 3.8
До того, как началось время жизни объекта, но после того, как хранилище, которое будет занимать объект, было распределено 34) или, после того, как время жизни объекта закончилось, и до хранилища, которое объект Занят, используется повторно или освобождается, любой указатель, который ссылается на место хранения, где объект будет или был расположен, может использоваться, но только ограниченным образом. Такой указатель относится к выделенному хранилищу (3.7.3.2), и с использованием
указатель, как если бы указатель был type void*
, четко определен. Такой указатель может быть разыменован, но результирующее lvalue может использоваться только ограниченным образом , как описано ниже. Если объект будет или имел тип класса с нетривиальным деструктором, и указатель используется в качестве операнда выражения удаления, программа имеет неопределенное поведение. Если объект будет или имел тип класса не POD, программа имеет неопределенное поведение, если:
- .......