Reputation: 17670
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
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
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
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