C ++ - "Most important const" doesn't work with expressions?

According to Herb Sutter's article http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ , the following code is correct:

#include <iostream>
#include <vector>
using namespace std;

vector<vector<int>> f() { return {{1},{2},{3},{4},{5}}; }

int main()
{
    const auto& v = f();
    cout << v[3][0] << endl;
}

      

i.e. the lifetime v

extends to the lifetime of the v

const reference . And indeed it compiles with gcc and clang and works without leaks according to valgrind.

However, when I change the function main

like this:

int main()
{
    const auto& v = f()[3];
    cout << v[0] << endl;
}

      

it still compiles, but valgrind warns me about invalid reads on the second line of the function due to the memory being free on the first line.

Is this standard compatible behavior or could it be a bug in both g ++ (4.7.2) and clang (3.5.0-1 ~ exp1)?

If it's standard compliant, I find it rather odd ... well, okay.

+3


source to share


1 answer


There are no errors here except for the code.

The first example works because when you bind a result from f()

to v

, you are extending the lifetime of that result.

In the second example, you are not binding the result f()

to anything, so its lifespan is not extended. Binding to a subobject will be considered:

[C++11: 12.2/5]:

The second context is when the link is attached to a temporary one. Temporary linking of a link, or a temporary one that is the complete object of the sub-object to which the link is attached, is preserved for the lifetime of the link , except for: [..]



& hellip; but you don't: you are binding to the result of calling a member function (for example operator[]

) of an object, and that result is not a vector data member!

(Remarkably, if you had std::array

, and not std::vector

, the & dagger; code would be absolutely correct, since the array data is stored locally, so the elements are subobjects.)

So, you have a dangling link to an original result boolean f()

that has long since gone out of scope.

& dagger; Sorry for the terrible initializers, but, well, blame the C ++.

+11


source







All Articles