taking address of temporary object

  • Thread starter V.Subramanian, India
  • Start date
V

V.Subramanian, India

The following post is for learning purpose only.
I am using g++ 3.4.3
Consider the following program x.cpp

#include <cstdlib>
#include <iostream>
#include <ostream>

using namespace std;

class Test {
public:
explicit Test(int arg = 0);
Test& operator+=(const Test& rhs);
int value() const;
private:
int x;
};

inline Test::Test(int arg) : x(arg)
{
}

inline Test& Test::eek:perator+=(const Test& rhs)
{
x += rhs.value();
return *this;
}

inline int Test::value() const
{
return x;
}

inline const Test operator+(const Test& lhs,
const Test& rhs)
{
Test temp(lhs);
return temp += rhs;
}

int main()
{
Test x(100);
Test y(200);
const Test* p = &(x + y);

int a = 10;
int b = 20;
const int* i = &(a + b);

return EXIT_SUCCESS;
}

When I compile this program x.cpp as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
I get the following warning and error.

x.cpp: In function `int main()':
x.cpp:42: warning: taking address of temporary
x.cpp:46: error: non-lvalue in unary `&'
x.cpp:42: warning: unused variable 'p'
x.cpp:46: warning: unused variable 'i'

Question:
In the above code, why does the compiler give warning for
taking the address of temporary-class-object namely
(x + y) whereas it generates error for taking the address of
temporary-built-in-object namely (a + b) ? I expected error
message for taking &(x + y) similar to that of &(a + b).

Is ithis behaviour specific to g++3.4.3 ? Or the standard
itself requires so ?

Please explain.

Thanks
V.Subramanian
 
V

Victor Bazarov

The following post is for learning purpose only.
I am using g++ 3.4.3
Consider the following program x.cpp

#include<cstdlib>
#include<iostream>
#include<ostream>

using namespace std;

class Test {
public:
explicit Test(int arg = 0);
Test& operator+=(const Test& rhs);
int value() const;
private:
int x;
};

inline Test::Test(int arg) : x(arg)
{
}

inline Test& Test::eek:perator+=(const Test& rhs)
{
x += rhs.value();
return *this;
}

inline int Test::value() const
{
return x;
}

inline const Test operator+(const Test& lhs,
const Test& rhs)
{
Test temp(lhs);
return temp += rhs;
}

int main()
{
Test x(100);
Test y(200);
const Test* p =&(x + y);

int a = 10;
int b = 20;
const int* i =&(a + b);

return EXIT_SUCCESS;
}

When I compile this program x.cpp as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
I get the following warning and error.

x.cpp: In function `int main()':
x.cpp:42: warning: taking address of temporary
x.cpp:46: error: non-lvalue in unary `&'
x.cpp:42: warning: unused variable 'p'
x.cpp:46: warning: unused variable 'i'

Question:
In the above code, why does the compiler give warning for
taking the address of temporary-class-object namely
(x + y) whereas it generates error for taking the address of
temporary-built-in-object namely (a + b) ? I expected error
message for taking&(x + y) similar to that of&(a + b).

Is ithis behaviour specific to g++3.4.3 ? Or the standard
itself requires so ?

Please explain.

I think the answer lies in the fact that a temporary object of a class
type (especially one that has a c-tor) usually resides in memory anyway
(and the compiler knows that), so taking its address is not a totally
impossible operation, whereas a temporary of a built-in type can easily
reside in the CPU register which does not have an address.

A class object that has any non-static member functions must have the
unique "this" pointer when the control is inside that function, which
means that even a temporary has to reside in memory.

V
 
A

Alf P. Steinbach

The following post is for learning purpose only.
I am using g++ 3.4.3
Consider the following program x.cpp

#include<cstdlib>
#include<iostream>
#include<ostream>

using namespace std;

class Test {
public:
explicit Test(int arg = 0);
Test& operator+=(const Test& rhs);
int value() const;
private:
int x;
};

inline Test::Test(int arg) : x(arg)
{
}

inline Test& Test::eek:perator+=(const Test& rhs)
{
x += rhs.value();
return *this;
}

inline int Test::value() const
{
return x;
}

inline const Test operator+(const Test& lhs,
const Test& rhs)
{
Test temp(lhs);
return temp += rhs;
}

int main()
{
Test x(100);
Test y(200);
const Test* p =&(x + y);

int a = 10;
int b = 20;
const int* i =&(a + b);

return EXIT_SUCCESS;
}

Please convert tabs to spaces before posting.

When I compile this program x.cpp as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
I get the following warning and error.

x.cpp: In function `int main()':
x.cpp:42: warning: taking address of temporary
x.cpp:46: error: non-lvalue in unary `&'
x.cpp:42: warning: unused variable 'p'
x.cpp:46: warning: unused variable 'i'

Hm, it should not compile at all. Lemme test.

g++ -std=c++98 -pedantic -Wall -Wextra foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:42:25: error: taking address of temporary [-fpermissive]
foo.cpp:46:24: error: lvalue required as unary '&' operand
foo.cpp:42:14: warning: unused variable 'p' [-Wunused-variable]
foo.cpp:46:13: warning: unused variable 'i' [-Wunused-variable]

[d:\dev\test]
</test>

Solution: upgrade to more recent version of the compiler.

Question:
In the above code, why does the compiler give warning for
taking the address of temporary-class-object namely
(x + y) whereas it generates error for taking the address of
temporary-built-in-object namely (a + b) ? I expected error
message for taking&(x + y) similar to that of&(a + b).

I think it must be a very old version of g++ you're using.

The Holy Standard does not permit using the built-in address operator to
take the address of a temporary.

Is ithis behaviour specific to g++3.4.3 ? Or the standard
itself requires so ?

Specific.


Cheers & hth.,

- Alf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top