By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,190 Members | 967 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,190 IT Pros & Developers. It's quick & easy.

Understanding temporary objects / taking address

P: n/a
I have a function which gets the adress of an object as argument.
It does some comparsion with the object's contents and then returns.
no Reference or pointer to the object is stored or will be used after
the function has returned.

Say the function whould be named f and the objects class whould be T
it'll look like this:

bool f(T* thing) {
return thing->foobar == 5; // Just a stupid example
}

When I now write a piece of code like this:

bool yesorno = f(&T(77));

I get a warning because I take the address of a temporary object.
Im not sure if this is okay or not here.
Does the object live long enough so f can do its operations on it?

Is it generally a good idea to to such things?
Or should I create an extra local variable which holds T(77)?
(As I will have lots of these calls that whould be unhandy as I use
different subclasses of T and you can Imagine using new and delete for
every call whuld be even unhandier.)

TIA
Henning
Jun 28 '06 #1
Share this Question
Share on Google+
17 Replies


P: n/a
In article <e7**********@rzcomm2.rz.tu-bs.de>,
Henning Hasemann <h.********@tu-bs.de> wrote:
I have a function which gets the adress of an object as argument.
It does some comparsion with the object's contents and then returns.
no Reference or pointer to the object is stored or will be used after
the function has returned.

Say the function whould be named f and the objects class whould be T
it'll look like this:

bool f(T* thing) {
return thing->foobar == 5; // Just a stupid example
}

When I now write a piece of code like this:

bool yesorno = f(&T(77));

I get a warning because I take the address of a temporary object.
Im not sure if this is okay or not here.
Does the object live long enough so f can do its operations on it?

Is it generally a good idea to to such things?
Or should I create an extra local variable which holds T(77)?
(As I will have lots of these calls that whould be unhandy as I use
different subclasses of T and you can Imagine using new and delete for
every call whuld be even unhandier.)


Try changing 'f' to:

bool f( const T* thing );
Jun 28 '06 #2

P: n/a

"Henning Hasemann" <h.********@tu-bs.de> wrote in message
news:e7**********@rzcomm2.rz.tu-bs.de...
I have a function which gets the adress of an object as argument.
It does some comparsion with the object's contents and then returns.
no Reference or pointer to the object is stored or will be used after
the function has returned.

Say the function whould be named f and the objects class whould be T
it'll look like this:

bool f(T* thing) {
return thing->foobar == 5; // Just a stupid example
}

When I now write a piece of code like this:

bool yesorno = f(&T(77));

I get a warning because I take the address of a temporary object.
Im not sure if this is okay or not here.
Does the object live long enough so f can do its operations on it?

Is it generally a good idea to to such things?
Or should I create an extra local variable which holds T(77)?
(As I will have lots of these calls that whould be unhandy as I use
different subclasses of T and you can Imagine using new and delete for
every call whuld be even unhandier.)


I'd prefer to use a const reference as the parameter, myself. That lets you
pass a temporary object fine, with no warnings, (and also handles the
polymorphism correctly, just like a pointer). I only use pointers if I have
to.

-Howard

Jun 28 '06 #3

P: n/a
Henning Hasemann posted:

Say the function whould be named f and the objects class whould be T
it'll look like this:

bool f(T* thing) {
return thing->foobar == 5; // Just a stupid example
}

When I now write a piece of code like this:

bool yesorno = f(&T(77));

I get a warning because I take the address of a temporary object.
Im not sure if this is okay or not here.

That warning should be an error.

A temporary, nameless object is an R-value. You can't take the address of
a R-value.

If you really want to pass the address of a temporary to a function, try
this:

class ArbitraryClass {
public:
int a;
int b;

ArbitraryClass() : a(1), b(2) {}
};

bool Func( const ArbitraryClass *p )
{
return p->a == p->b;
}

template<class T>
const T *AdrsTmp( const T &temp ) { return &temp; }
int main()
{
Func( AdrsTmp( ArbitraryClass() ) );
}
A temporary lives on until the end of the statement; so the temporary in
the above code gets killed at the end of the semi-colon in "main".

I wonder what people would think if I rewrote "AdrsTmp" like as follows:

template<class T>
T *AdrsTmp( const T &temp ) { return const_cast<T*>(&temp); }
We know that it's pefectly okay to cast away constness if the object in
question is in fact non-const. The temporary in "main" is non-const --
that's for sure. However... is the "AdrsTmp" function free to create
another temporary when it takes its argument, rather than work with the
temporary provided by main... ?
--

Frederick Gotham
Jun 28 '06 #4

P: n/a
Howard wrote:
I'd prefer to use a const reference as the parameter, myself. That lets you
pass a temporary object fine, with no warnings, (and also handles the
polymorphism correctly, just like a pointer). I only use pointers if I have
to.


In this case I have to, as f actually is the contains() method of a
set-template-class and the template Parameter is a pointer type but
could be a non-pointer type as well.

I think Daniel T.'s solution with using a const pointer was what I was
looking for.

Thanks you 2.

Henning
Jun 28 '06 #5

P: n/a
Frederick Gotham wrote:
Henning Hasemann posted:
A temporary lives on until the end of the statement; so the temporary in
the above code gets killed at the end of the semi-colon in "main".


Hmm.
Shouldnt this be long enough then? At the end of the semicolon Func has
returned, so I got what I needed, or?

I think I half-way understood your wrapper but (still) not exactly why
it is necessary.
If it is such a problem to give away the adress of a temporary, is there
a better way in my case?

Maybe I should tell a bit more od what Im doing. The function I talk
about is the contains-Method of a template-class for a set (Yes I know
of STL, there are reasons for implementing my own).

It looks roughly like this:

template<class T>
class MySet {
public:
// ...
bool contains(const T item) const {
// look at item and return true if
// we have something that is considered to be equal
// ...
}
};

The problematic case is the one, where T is a pointer-type.
As I put different subclasses of T into this set and often look if a
certain item is contained a (to the caller of contains()) local variable
is as unpleasant as creating and deleting objects for each contains() on
the heap.

Henning

Jun 28 '06 #6

P: n/a
Henning Hasemann posted:
Frederick Gotham wrote:
Henning Hasemann posted:
A temporary lives on until the end of the statement; so the temporary
in the above code gets killed at the end of the semi-colon in "main".
Hmm.
Shouldnt this be long enough then? At the end of the semicolon Func
has returned, so I got what I needed, or?

Yes, exactly.

I think I half-way understood your wrapper but (still) not exactly why
it is necessary.
If it is such a problem to give away the adress of a temporary, is
there a better way in my case?

Well you can continue on with what you're doing, i.e. just stick the
"address of" operator before a nameless temporary:

&ArbitraryClass()

but the C++ Standard forbids this, because you're taking the address of
an R-value. Your compiler is being lenient by letting you do it.

My own code however is perfectly Standard-compliant, because I don't take
the address of an R-value. (Once the object gets bound to a const
reference, you can use the const reference as an L-value).

It's sort of like walking to the checkout with your wife, aiming to buy 6
packets of Aspirin. In line with the Laws of the Land, the cashier
informs you that he can only sell you a maximum of 3 packets, so you tell
him "That's fine", and you just buy 3 packets. Having finalised the
transaction, you then hand the rest of the money to your wife, and she
buys another 3 packets of Aspirin. Sure, it isn't exactly how things are
supposed to work, but by going through the formalities, you haven't
broken the rules.

Think of my template function as your wife ; )

--

Frederick Gotham
Jun 28 '06 #7

P: n/a
Frederick Gotham wrote:
Henning Hasemann posted:
but the C++ Standard forbids this, because you're taking the address of
an R-value. Your compiler is being lenient by letting you do it.
Ah okay.
That surprises me a bit though. As I use "g++ (GCC) 3.3.6" with -ansi I
thought it whould be already very strict.
It's sort of like walking to the checkout with your wife, aiming to buy 6
packets of Aspirin. In line with the Laws of the Land, the cashier
informs you that he can only sell you a maximum of 3 packets, so you tell
him "That's fine", and you just buy 3 packets. Having finalised the
transaction, you then hand the rest of the money to your wife, and she
buys another 3 packets of Aspirin. Sure, it isn't exactly how things are
supposed to work, but by going through the formalities, you haven't
broken the rules.

Think of my template function as your wife ; )


Well okay, i finally got the point :-)

I'll just leave it the dirty way for now and consider to use your
"adapter" or something else when theres time, fortunately the warning
will remind me sometimes of this.

Thanks for you time :)

Henning

Jun 28 '06 #8

P: n/a
On Wed, 28 Jun 2006 18:01:58 +0200, Henning Hasemann
<h.********@tu-bs.de> wrote:
Howard wrote:
I'd prefer to use a const reference as the parameter, myself. That lets you
pass a temporary object fine, with no warnings, (and also handles the
polymorphism correctly, just like a pointer). I only use pointers if I have
to.


In this case I have to, as f actually is the contains() method of a
set-template-class and the template Parameter is a pointer type but
could be a non-pointer type as well.


If you have to use pointers (which is not actually clear from your
answer) you should handle pointers appropriately:

bool f (const T* thing) {
return thing && thing->foobar == 5; // Just a stupid example
}

Best wishes,
Roland Pibinger
Jun 28 '06 #9

P: n/a
Henning Hasemann posted:
I'll just leave it the dirty way for now and consider to use your
"adapter" or something else when theres time, fortunately the warning
will remind me sometimes of this.

Of course, you could use a simple static_cast:
#include <string>

void Func( const std::string * );

int main()
{
Func( &static_cast<const std::string &>( std::string() ) );
}

--

Frederick Gotham
Jun 28 '06 #10

P: n/a
Henning Hasemann wrote:
bool yesorno = f(&T(77));

I get a warning because I take the address of a temporary object.
Im not sure if this is okay or not here.
Does the object live long enough so f can do its operations on it?


It's not OK to apply & to a non-lvalue. The language says unary-&
gets applied to an lvalue (for simple pointers) or a qualified-id
(for poitner to member).
Jun 29 '06 #11

P: n/a
Daniel T. wrote:
Try changing 'f' to:

bool f( const T* thing );


How does that help. The error is not in the call to f() but
in the illegal application of unary& to an rvalue.

Jun 29 '06 #12

P: n/a
Henning Hasemann wrote:
In this case I have to, as f actually is the contains() method of a
set-template-class and the template Parameter is a pointer type but
could be a non-pointer type as well.

I think Daniel T.'s solution with using a const pointer was what I was
looking for.

No it's not. It's just as wrong as you had before.
Jun 29 '06 #13

P: n/a

Hi ,
u have writtten " The temporary in "main" is non-const -- that's for
sure. "
Is constantness of temporary object compiler dependent ? Because
somewhere on
net i remember reading that temporary object created by compiler are
constant , but i can't recall name of compiler .

Regards ,
Mangesh Sawant .
Frederick Gotham wrote:
Henning Hasemann posted:

Say the function whould be named f and the objects class whould be T
it'll look like this:

bool f(T* thing) {
return thing->foobar == 5; // Just a stupid example
}

When I now write a piece of code like this:

bool yesorno = f(&T(77));

I get a warning because I take the address of a temporary object.
Im not sure if this is okay or not here.

That warning should be an error.

A temporary, nameless object is an R-value. You can't take the address of
a R-value.

If you really want to pass the address of a temporary to a function, try
this:

class ArbitraryClass {
public:
int a;
int b;

ArbitraryClass() : a(1), b(2) {}
};

bool Func( const ArbitraryClass *p )
{
return p->a == p->b;
}

template<class T>
const T *AdrsTmp( const T &temp ) { return &temp; }
int main()
{
Func( AdrsTmp( ArbitraryClass() ) );
}
A temporary lives on until the end of the statement; so the temporary in
the above code gets killed at the end of the semi-colon in "main".

I wonder what people would think if I rewrote "AdrsTmp" like as follows:

template<class T>
T *AdrsTmp( const T &temp ) { return const_cast<T*>(&temp); }
We know that it's pefectly okay to cast away constness if the object in
question is in fact non-const. The temporary in "main" is non-const --
that's for sure. However... is the "AdrsTmp" function free to create
another temporary when it takes its argument, rather than work with the
temporary provided by main... ?
--

Frederick Gotham


Jun 29 '06 #14

P: n/a
mangesh wrote:

Please don't top post and use gibberish such as 'u'.
Frederick Gotham wrote:


template<class T>
const T *AdrsTmp( const T &temp ) { return &temp; }
int main()
{
Func( AdrsTmp( ArbitraryClass() ) );
}
A temporary lives on until the end of the statement; so the temporary in
the above code gets killed at the end of the semi-colon in "main".

I wonder what people would think if I rewrote "AdrsTmp" like as follows:

template<class T>
T *AdrsTmp( const T &temp ) { return const_cast<T*>(&temp); }
We know that it's pefectly okay to cast away constness if the object in
question is in fact non-const. The temporary in "main" is non-const --
that's for sure. However... is the "AdrsTmp" function free to create
another temporary when it takes its argument, rather than work with the
temporary provided by main... ?

Hi ,
u have writtten " The temporary in "main" is non-const -- that's for
sure. "
Is constantness of temporary object compiler dependent ? Because
somewhere on
net i remember reading that temporary object created by compiler are
constant , but i can't recall name of compiler .

No, the temporary is an rvalue. It can be assigned to a const
reference, but as a value, you can take it's address. All the wrapper
does is assign it to a const reference and take the address of the
reference.

A bit like:

const int& i = 42;

const int* p = &i;

42 is an rvalue, so you can assign it to a const reference, but you
couldn't take its address.

--
Ian Collins.
Jun 29 '06 #15

P: n/a
In article <44***********************@news.newshosting.com> ,
Ron Natalie <ro*@spamcop.net> wrote:
Daniel T. wrote:
Try changing 'f' to:

bool f( const T* thing );


How does that help. The error is not in the call to f() but
in the illegal application of unary& to an rvalue.


It doesn't. Sorry, I was wrong to suggest it.
Jun 29 '06 #16

P: n/a
mangesh posted:

Hi , u have writtten " The temporary in "main" is non-const -- that's
for sure. " Is constantness of temporary object compiler dependent ?
Because somewhere on net i remember reading that temporary object
created by compiler are constant , but i can't recall name of compiler
.


And I'm glad you can't remember the name of any such compiler.

Let's start off with writing a very simple class which has a member
function which comes in two flavours: The const flavour, and the non-
const flavour.

#include <iostream>

class Arb {
public:

int a;
void Method()
{
a = 7;

std::cout << "The NON-const method was called.\n";
}

void Method() const
{
std::cout << "The CONST method was called.\n";
}
};
Now let's make two typedef's:

typedef Arb NonConstArb;
typedef Arb const ConstArb;
And now let's create two nameless temporaries, one which we intend to be
const, and the other which we intend to be non-const:
int main()
{
NonConstArb();

ConstArb();
}
And now let's invoke our member function upon each of them and see what
happens:
int main()
{
NonConstArb().Method();

ConstArb().Method();
}
I hope the output pleases you.
--

Frederick Gotham
Jun 29 '06 #17

P: n/a
Hi ,
thanks for clearing my doubt .

Regrds ,
Mangesh .

Frederick Gotham wrote:
mangesh posted:

Hi , u have writtten " The temporary in "main" is non-const -- that's
for sure. " Is constantness of temporary object compiler dependent ?
Because somewhere on net i remember reading that temporary object
created by compiler are constant , but i can't recall name of compiler
.


And I'm glad you can't remember the name of any such compiler.

Let's start off with writing a very simple class which has a member
function which comes in two flavours: The const flavour, and the non-
const flavour.

#include <iostream>

class Arb {
public:

int a;
void Method()
{
a = 7;

std::cout << "The NON-const method was called.\n";
}

void Method() const
{
std::cout << "The CONST method was called.\n";
}
};
Now let's make two typedef's:

typedef Arb NonConstArb;
typedef Arb const ConstArb;
And now let's create two nameless temporaries, one which we intend to be
const, and the other which we intend to be non-const:
int main()
{
NonConstArb();

ConstArb();
}
And now let's invoke our member function upon each of them and see what
happens:
int main()
{
NonConstArb().Method();

ConstArb().Method();
}
I hope the output pleases you.
--

Frederick Gotham


Jun 30 '06 #18

This discussion thread is closed

Replies have been disabled for this discussion.