Reference a Temporary in Msvc

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



Leave a reply



Submit