3

I am practicing things described Here to learn the concept of lvalue and rvalue.

However, when I contrive my own example as follows, I find it compiles and runs without any error (using VS2017). I have learnt that in case 1, it is the same as calling

produceA(10).operator=(A()) 

and thus is legal. But, I still don't understand why case 2 and 3 are allowed. In fact, case 2 even contradicts the example given in the article. Am I actually getting the addresses of rvalues in these 2 cases? Do they lead to undefined behavior?

#include <string>

class A
{
    int data = 1;
public:
    A() = default;

    A(int in)
    : data(in)
    {}

    A& operator=(const A& rhs)
    {
        data = rhs.data;
        return *this;
    }
};

A produceA(int i)
{
    A a(i);
    return a;
}


int main()
{
    // case 1
    produceA(10) = A();

    // case 2
    A* pa = &produceA(10);    // rvalue?

    // case 3
    std::string* pstr = &std::string("Temp");    // rvalue?

    return 0;
}
Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Your sample code [does not compile](http://coliru.stacked-crooked.com/a/a5adcbe34052d925). What compiler are you using? – Quentin Oct 10 '17 at 08:58
  • I tried this on both VS2013 and VS2017. Both them give no error. – Larry Liang Oct 10 '17 at 09:16
  • 1
    Thanks so much. I also find [this one](https://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug) after your hint. Using command option /Za makes case 2 and 3 errors. The purpose behind this extension seems so mysterious to me. :/ – Larry Liang Oct 10 '17 at 09:48

1 Answers1

0

&produceA(10) is the address of the anonymous temporary of type A returned back from the function. You are allowed to set a pointer to it, but that pointer is only valid for the lifetime of the entire statement.

The same can be said for &std::string("Temp"); again, this is an address of an anonymous temporary.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • But... You can't take the address of a temporary :/ `error: taking the address of a temporary object of type 'A' [-Waddress-of-temporary]` – Quentin Oct 10 '17 at 08:56