Why is taking the address of a temporary illegal?

Prasoon Saurav picture Prasoon Saurav · Nov 29, 2010 · Viewed 10.8k times · Source

I know that the code written below is illegal

void doSomething(std::string *s){}
int main()
{
     doSomething(&std::string("Hello World"));
     return 0;
}

The reason is that we are not allowed to take the address of a temporary object. But my question is WHY?

Let us consider the following code

class empty{};
int main()
{
      empty x = empty(); //most compilers would elide the temporary
      return 0;
}

The accepted answer here mentions

"usually the compiler consider the temporary and the copy constructed as two objects that are located in the exact same location of memory and avoid the copy."

According to the statement it can be concluded that the temporary was present in some memory location( hence its address could have been taken) and the compiler decided to eliminate the temporary by creating an in-place object at the same location where the temporary was present.

Does this contradict the fact that the address of a temporary cannot be taken?

I would also like to know how is return value optimization implemented. Can someone provide a link or an article related to RVO implementation?

Answer

James McNellis picture James McNellis · Nov 29, 2010
&std::string("Hello World")

The problem with this isn't that std::string("Hello World") yields a temporary object. The problem is that the expression std::string("Hello World") is an rvalue expression that refers to a temporary object.

You cannot take the address of an rvalue because not all rvalues have addresses (and not all rvalues are objects). Consider the following:

42

This is an integer literal, which is a primary expression and an rvalue. It is not an object, and it (likely) does not have an address. &42 is nonsensical.

Yes, an rvalue may refer to an object, as is the case in your first example. The problem is that not all rvalues refer to objects.