Reference a temporary in msvc
It compiles because MSVC has a non-standard compliant "extension" that allows binding non-const references to temporaries.
The first example should not compile on a standards compliant compiler.
In the second example, you are taking the address of a temporary to set the value of a pointer. This should also result in an error.
Clang 3.2 produces:
error: taking the address of a temporary object of type 'Foo' [-Waddress-of-temporary]
while GCC 4.7.3 produces
error: taking address of temporary [-fpermissive]
c++ initializing lvalue reference with a temporary object rvalue as well as auto deduction
If you compile with the /Wall
flag, you will be given the answer by the compiler itself:
warning C4239: nonstandard extension used: 'initializing': conversion from 'A' to 'A &'
note: A non-const reference may only be bound to an lvalue
warning C4239: nonstandard extension used: 'initializing': conversion from 'A' to 'A &'
note: A non-const reference may only be bound to an lvalue
I.e., the program is indeed ill-formed as per the C++17 standard, but leverages a MSVC non-standard extension. Note that your program is rejected for /std:latest
, which arguably seems like a good decision on MSVC's side, as this is quite a dangerous extension.
DEMO.
Why is the returning reference to temporary object compiler warning not triggered?
It looks like it is a bug in Visual Studio, you can find it was reported for VS 2012 and it appears it was still present in 2013:
https://connect.microsoft.com/VisualStudio/feedback/details/776530/warning-c4172-not-emitted
Above link might be a duplicate of some other, the example from this bug report looks quite the same as your sample code:
// main.cpp
struct A
{
};
struct B
{
A a() const {return A();}
};
struct C
{
A const& a() const
{
return B().a();
}
};
int main()
{
return 0;
}
c++ can a temporary lambda be passed by reference (works on msvc/windows but not gcc/linux)?
MSVC deviates from the standard in that it allows anonymous temporaries to be bound to non-const lvalue references. You can switch this off using the /Za
compiler flag ("disable language extensions"), or the sharper /permissive-
option from MSVC2017.
The C++ standard has always been clear that anonymous temporaries can only bind to const
references.
Dangling reference when returning reference to reference parameter bound to temporary
I like to keep an example class A
around for situations like this. The full definition of A
is a little too lengthy to list here, but it is included in its entirety at this link.
In a nutshell, A
keeps a state
and a status
, and the status
can be one of these enums:
destructed = -4,
self_move_assigned = -3,
move_assigned_from = -2,
move_constructed_from = -1,
constructed_specified = 0
That is, the special members set the status accordingly. For example ~A()
looks like this:
~A()
{
assert(is_valid());
--count;
state_ = randomize();
status_ = destructed;
}
And there's a streaming operator that prints this class out.
Language lawyer disclaimer: Printing out a destructed A
is undefined behavior, and anything could happen. That being said, when experiments are compiled with optimizations turned off, you typically get the expected result.
For me, using clang
at -O0
, this:
#include "A.h"
#include <iostream>
int
main()
{
A a{1};
A b{2};
A c{3};
A&& x = a + b + c;
std::cout << x << '\n';
}
Outputs:
destructed: -1002199219
Changing the line to:
A x = a + b + c;
Results in:
6
Related Topics
Changing the Value of Const Variable in C++
Benchmarking (Python VS. C++ Using Blas) and (Numpy)
Vector or Map, Which One to Use
How to Generate a Random Double Uniformly Distributed Between 0 and 1 from C++
Getting an Accurate Execution Time in C++ (Micro Seconds)
Are Move Constructors Produced Automatically
Use Wm_Copydata to Send Data Between Processes
C++: Rationale Behind Hiding Rule
What Is an Iterator's Default Value
How to Use Openssl's Sha256 Functions
Access Array Beyond the Limit in C and C++
Should I Store Entire Objects, or Pointers to Objects in Containers
What Is the Simplest Way to Convert Array to Vector
How to Sort a Std::Map First by Value, Then by Key
Reorder Vector Using a Vector of Indices
Accessing a Protected Member of a Base Class in Another Subclass
What Is a Glibc Free/Malloc/Realloc Invalid Next Size/Invalid Pointer Error and How to Fix It