Specifically, is the following legal C++?
class A{}; void foo(A*); void bar(const A&); int main(void) { foo(&A()); // 1 bar(A()); // 2 }
It a
1: Taking the address of a temporary is not allowed. Visual C++ allows it as a language extension (language extensions are on by default).
2: This is perfectly legal.
No, it's against the standard to pass a non-const reference to a temporary object. You can use a const reference:
class A{};
void bar(const A&);
int main(void)
{
bar(A()); // 2
}
So while some compliers will accept it, and it would work as long as don't use the memory after the semicolon, a conforming compiler will not accept it.
Those A objects will only exist until execution reaches the semicolon. So, the calls are safe, but don't try to save the pointer and use it later. Also, the compiler may require bar take a const reference.
foo is not allowed in fully standard compliant C++, whereas bar is okay. Though chances are, foo will compile with warning, and bar may or may not compile with a warning as well.
A() create a temporary object, which unless bound to a reference (as is the case in bar), or used to initialize a named object, is destroyed at the end of the full expression in which it was created. A temporary created to hold a reference initializer persists until the end of its reference's scope. For the case of bar, that's the function call, so you can use A inside bar perfectly safely. It is forbidden to bound a temporary object (which is a rvalue) to a non-const reference. It is similarly forbidden to take the address of a rvalue (to pass as argument to initialize A for foo).
for //2 you need a const reference
for //1 I think it's legal but useless
It looked lke it would work, but it did not compile with g++ with the Wall option, here is what I get:
michael@hardy-lenovo:~/Desktop$ g++ -Wall a.cpp a.cpp: In function ‘int main()’:michael@hardy-lenovo:~/Desktop$ g++ -Wall a.cpp a.cpp: In function ‘int main()’: a.cpp:8: warning: taking address of temporary a.cpp:9: error: invalid initialization of non-const reference of type ‘A&’ from a temporary of type ‘A’ a.cpp:4: error: in passing argument 1 of ‘void bar(A&)’ michael@hardy-lenovo:~/Desktop$
Looks like you will need to use a constant reference.