This question can be considered a follow-up to the following question: C++ temporary variable lifetime.
Qt
containers support the stream-like
initialization syntax. Now, when I write the following code, my QVector
is destructed right after assignment and the reference becomes dangling.
const QVector<QString>& v = QVector<QString>() << "X" << "Y" << "Z";
Corresponding operator<<
is implemented the following way:
inline QVector<T> &operator<< (const T &t)
{ append(t); return *this; }
As far as I know, 10.4.10 Temporary Objects
states that the lifetime of a temporary object is extended to match the lifetime of the correspnding const
reference to it.
However, in this case the temporary object QVector<QString>()
is destructed earlier.
I guess that probably this happens due to the fact that the last operation returns a QVector<QString>&
and shouldn't know anything about the lifetime of the temporary QVector<QString>
, but this explanation isn't strict and might be wrong.
So, why does this happen?
What is the Lifetime of a variable in C? Lifetime of a variable is defined as for how much time period a variable is occupying a valid space in the system's memory or lifetime is the period between when memory is allocated to hold the variable and when it is freed. Once the variable is out of scope its lifetime ends.
The lifetime of a variable or object is the time period in which the variable/object has valid memory. Lifetime is also called "allocation method" or "storage duration."
Scope is about the 'availability' of the declared variable: within the same scope, it is not possible to declare/define two variables of the same type with the same name. Lifetime is about the duration in which the variable is 'alive': it determines how long the named or unnamed variable has memory allocated to it.
The lifetime of a temporary is only extended if it is bound to a const-reference:
const QVector<QString>& v = QVector<QString>();
However, in your code you are not binding the temporary to anything. Rather, you're calling a member function (of the temporary), which returns a reference (to the temporary). The result of this function call is no longer a temporary object, but just a plain reference. The original temporary object expires at the end of the full expression in which it appears, and the reference v
becomes dangling.
(In the new C++, it is possible to prohibit such "accidents" by virtue of rvalue-qualified member functions, i.e. you could =delete
the rvalue version of the <<
operator.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With