Search code examples
c++functionpointerslocalundefined-behavior

Is returning a pointer to a local variable always undefined behavior


I have read that we should not return a pointer or a reference to a local variable. So in the below given example, i understand that when i wrote: return f; inside function foo, i am returning a pointer to a local variable. And using that pointer outside the function, will lead to undefined behavior.

#include <iostream>

const char* foo()
{
    const char* f = "ffdf";
    return f;//returning pointer to a local variable
}

const char* func()
{
    return "fsfs";
}

int main()
{
    const char* ptr = func();
    const char* f = foo();
    std::cout<<f<<std::endl; //I know this is undefined behavior because we're using a pointer that points to a local variable 
    std::cout<<ptr; //But IS THIS UNDEFINED BEHAVIOR too?
}

My question is that does the same hold true for the return statement return "fsfs"; inside function func. I am aware that in C++17 there is mandatory copy elison. So my question is directed towards all modern C++ version(C++11, C++17, etc). Does the behavior depends/differs on C++ version.

In particular, i know that the statement std::cout<<f<<std::endl; inside main is always undefined behavior because we're using a pointer(dangling) that points to a local variable. But does the statement std::cout<<ptr; also leads to undefined behavior. If not why and what will happen here.

PS: I might be wrong in describing what is actually happening in the first cout statement too. So please correct me if i am wrong. Also, my original intention was not restricted to a particular type like a string literal. For example, i could've have chosen to return an int instead of a string literal and have the return type as const int&. But since people have already started answering i am not changing the example to use int.


Solution

  • Returning a pointer to a non-static function local variables will cause the pointer you get at the call site to be a dangling pointer and using it will have undefined behavior.

    Here, this is not the case. A string literal has static storage duration, meaning it will live until the end of the program. This means it is safe to return a pointer to a string literal that was declared in a function.

    So both foo and func are safe, but if you had

    const char * bar()
    {
        std::string text = "some text";
        // stuff
        return text.c_str();
    }
    

    Then you would be returning a pointer to an object that no longer exits and would have UB trying to read from that returned pointer.