consider something like this:
#include <iostream> struct C { C(double x=0, double y=0): x(x) , y(y) { std::cout << "C ctor " << x << " " <<y << " " << "\n"; } double x, y; }; struct B { B(double x=0, double y=0): x(x), y(y) {} double x, y; }; struct A { B b[12]; A() { b[2] = B(2.5, 14); b[4] = B(56.32,11.99); } }; int main() { const B& b = A().b[4]; C c(b.x, b.y); }
when I compile with -O0 I'm getting the print
C ctor 56.32 11.99
but when I compile with -O2 I'm getting
C ctor 0 0
I know we can use const reference to prolong a local temporary, so something like
const A& a = A(); const B& b = a.b;
would be perfectly legal. but I'm struggling to find the reasoning for why the same mechanism/rule doesn't apply for any kind of temporary
EDIT FOR FUTURE REFERENCE:
I'm using gcc version 6.3.0
You are not questioning why const references are allowed to bind to temporaries, but merely why they extend the lifetime of those temporaries. If the lifetime of the temporary returned by bar() were not extended, then any usage of a (exemplified by the line (1)) would lead to undefined behavior.
Pass Using Const Reference in C++ Now, we can use the const reference when we do not want any memory waste and do not change the variable's value. The above code will throw a compile error as num = num +10 is passed as a const reference.
You can declare the test function as: int test(gadget const &g); In this case, parameter g has type “reference to const gadget .” This lets you write the call as test(x) , as if it were passing by value, but it yields the exact same performance as if it were passing by address.
C does not support references or passing by reference. You should use pointers instead and pass by address. Pass-by-value is efficient for primitive types, but does a shallow copy for structs. In C++ it makes a LOT of sense to pass objects by reference for efficiency.
Your code should be well-formed, because for temporaries
(emphasis mine)
Whenever a reference is bound to a temporary or to a subobject thereof, the lifetime of the temporary is extended to match the lifetime of the reference
Given A().b[4]
, b[4]
is the subobject of b
and the data member b
is the subobject of the temproray A()
, whose lifetime should be extended.
LIVE on clang10 with -O2
LIVE on gcc10 with -O2
BTW: This seems to be a gcc's bug which has been fixed.
From the standard, [class.temporary]/6
The third context is when a reference is bound to a temporary object.36 The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained through one of the following:
...
[ Example:
template<typename T> using id = T; int i = 1; int&& a = id<int[3]>{1, 2, 3}[i]; // temporary array has same lifetime as a const int& b = static_cast<const int&>(0); // temporary int has same lifetime as b int&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0); // exactly one of the two temporaries is lifetime-extended
— end example ]
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