Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return a const reference to an empty string without a compiler warning?

Tags:

c++

string

I have a std::unordered_map<int, std::string> and a function GetString(int key) that takes an int key and returns a string value from this map.

When the key isn't found in the map, I have to return an empty string.

#include <iostream>
#include <string>
#include <unordered_map>

std::unordered_map<int, std::string> map
{
    { 5, "somelongstring" }
};

const std::string& GetString(int key)
{
    auto iterator = map.find(key);
    if (iterator == map.end())
    {
        return "";
    }

    return iterator->second;
}

int main()
{
    std::cout << GetString(1) << std::endl;
}

The problem is the compiler gives me this warning

warning C4172: returning address of local variable or temporary

(with MS Visual Studio 2013) or

warning: returning reference to temporary [-Wreturn-local-addr]

(with g++ 4.9.2)

One way to get out of this I found was to declare a static const std::string at the top and return that instead of the empty string literal

static const std::string Empty = "";

const std::string& GetString(int key)
{
    auto iterator = map.find(key);
    if (iterator == map.end())
    {
        return Empty;
    }

    return iterator->second;
}

But it didn't seem very clean to define an empty string literal. Is there a neat way to do this?

Update: My map is initialized once during startup and then read simultaneously from multiple threads (using GetString). Using a function static empty string wouldn't work because function static variables aren't initialized in a thread safe manner under visual studio's compiler.

like image 914
tcb Avatar asked May 14 '15 13:05

tcb


People also ask

Can you copy a const reference?

The const keyword marks my_vector as non-modifiable, while the reference symbol (&) states that it should not be copied. This is exactly the behaviour we would want out of a norm function.

What is returning reference in C++?

Returning values by reference in C++ A C++ function can return a reference in a similar way as it returns a pointer. When a function returns a reference, it returns an implicit pointer to its return value. This way, a function can be used on the left side of an assignment statement.

Can you change a const reference?

The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable—just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g., its properties) can be altered.

When should I return by reference?

You should return a reference to an existing object that isn't going away immediately, and where you don't intend any transfer of ownership. Never return a reference to a local variable or some such, because it won't be there to be referenced.


2 Answers

The warning message explicitely says what the problem is : you are returning the address of a local variable (""") that will be freed from stack after function returns. It would be fine to return a std::string, because you would construct a new string outside of the function local variables, but as you return a std::string& you do use the local variable.

But as you return a static value, just make it static :

const std::string& GetString(int key)
{
    static const string empty = "";
    auto iterator = map.find(key);
    if (iterator == map.end())
    {
        return empty;
    }

    return iterator->second;
}
like image 190
Serge Ballesta Avatar answered Oct 31 '22 21:10

Serge Ballesta


I would change the return type to either std::string (and so returning an empty string is ok) or to std::string * (returning nullptr for not found).

Otherwise the compiler is right: you can't return a reference to a local object about to be destoyed

like image 4
marom Avatar answered Oct 31 '22 20:10

marom