Ruggero Turra
Ruggero Turra

Reputation: 17670

reference to a temporary and warnings

I've lost one hour to find this problem in my code:

vector<string> & input_variables = parse_xml(xml_path)["variables"];

where parse_xml is a function returning a std::map<std::string, std::vector<std::string> >. Why gcc is not warning me (with -Wall)? Am I missing some flags?

Upvotes: 0

Views: 173

Answers (3)

Nicol Bolas
Nicol Bolas

Reputation: 473302

GCC doesn't warn you because technically there's nothing to warn about.

parse_xml() returns a std::map by value, which is a temporary. Calling operator[] returns a reference. The compiler cannot know locally that this reference is actually part of the std::map temporary. For all the compiler knows, operator[] could be returning a reference to a global or something.

A member variable of a temporary is considered a temporary, which is linked to the lifetime of the outer temporary. But the return value of a function (like operator[]) is not so linked.

Upvotes: 1

Šimon T&#243;th
Šimon T&#243;th

Reputation: 36433

The reason why it doesn't warn you is because you are getting an invalid operation through a sequence of valid steps:

struct X
{
    int c;
    int & operator [] (int) { return c; } /* this is perfectly OK */
};

X f()
{
    return X(); /* this is perfectly OK */
}

int main()
{
    int &x = f()[1]; /* can apply [] on temporary, therefore OK */
}

You can prevent this from occurring by explicitly marking the result of f() as const.

Upvotes: 0

Puppy
Puppy

Reputation: 146910

You have taken a reference to an object which is destroyed. In C++11 new language features are written in making this code illegal. You must make a copy or swap the data into a local variable if you wish to use it. GCC is not warning you because C++03 does not provide the necessary features to prevent such.

Technically, the return value of operator[] is an lvalue. Unfortunately, it is about to be destroyed by it's owner, the std::map.

Upvotes: 2

Related Questions