Alex Rivera | Logout

Why is taking the address of a temporary illegal?

Asked 2010-11-29T05:53:28.337
15

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?

Edit
Report

1 Answer

3

A temporary is an example of a C++ "rvalue." It is supposed to purely represent a value within its type. For example, if you write 42 in two different places in your program, the instances of 42 are indistinguishable despite probably being in different locations at different times. The reason you can't take the address is that you need to do something to specify that there should be an address, because otherwise the concept of an address is semantically unclean and unintuitive.

The language requirement that you "do something" is somewhat arbitrary, but it makes C++ programs cleaner. It would suck if people made a habit of taking addresses of temporaries. The notion of an address is intimately bound with the notion of a lifetime, so it makes sense to make "instantaneous" values lack addresses. Still, if you are careful, you can acquire an address and use it within the lifetime that the standard does allow.

There are some fallacies in the other answers here:

  • "You cannot take the address of an rvalue because not all rvalues have addresses." — Not all lvalues have addresses either. A typical local variable of type int which participates in a simple loop and is subsequently unused will likely be assigned a register but no stack location. No memory location means no address. The compiler will assign it a memory location if you take its address, though. The same is true of rvalues, which may be bound to const references. The "address of 42" may be acquired as such:

    int const *fortytwo_p = & static_cast<int const &>( 42 );
    

    Of course, the address is invalid after the ; because temporaries are temporary, and this is likely to generate extra instructions as the machine may pointlessly store 42 onto the stack.

    It's worth mentioning that C++0x cleans up the concepts by defining the prvalue to b

answered 2010-11-29T06:34:45.203

Your Answer