473,651 Members | 2,743 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Understanding temporary objects / taking address

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
17 10264
In article <e7**********@r zcomm2.rz.tu-bs.de>,
Henning Hasemann <h.********@t u-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

"Henning Hasemann" <h.********@t u-bs.de> wrote in message
news:e7******** **@rzcomm2.rz.t u-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
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
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
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
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
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
On Wed, 28 Jun 2006 18:01:58 +0200, Henning Hasemann
<h.********@t u-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
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<co nst std::string &>( std::string() ) );
}

--

Frederick Gotham
Jun 28 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
1570
by: Vinodh Kumar | last post by:
#include <iostream> using namespace std; struct A { virtual void fa(); }; struct B : public A
19
2474
by: Kai-Uwe Bux | last post by:
Hi folks, I have trouble writing a class, derving from stringstream, that collects item and once it's done will write them to std::cout in one go. It works fine except when I use it as a temporary. Here is a tiny test programm: #include <iostream> #include <sstream>
2
1321
by: Hunter Hou | last post by:
Hello, I have some code to implement combination of composite and command patterns. Here is the problem: ====== class Number {
2
1928
by: Ariel | last post by:
When passing an object by value to some function foo(), the copy constructor gets called and inside it i see that the address of the temporary obect is X. but when entering to foo() i see that the address of the temporary object is Y. By looking at the assembly i think that the copiler copies the temporary object to a different location after calling the copy constructor. Is it legal? thanks ahead,
3
12882
by: daniell | last post by:
/* Triangle.cpp */ // Use a pure virtual function. #include <iostream> #include <cstring> using namespace std;
11
3342
by: venkatagmail | last post by:
I have problem understanding pass by value and pass by reference and want to how how they are or appear in the memory: I had to get my basics right again. I create an array and try all possible ways of passing an array. In the following code, fun1(int a1) - same as fun1(int* a1) - where both are of the type passed by reference. Inside this function, another pointer a1 is created whose address &a1 is different from that of the passed...
2
2365
by: anon.asdf | last post by:
Hello! 1) =============================== When trying to define an array of std::string ... func( (std::string ) { std::string("ab"), std::string("cd"), std::string("ef") } , 3 ); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ....g++ tells me: "invalid use of non-lvalue array"
5
2641
by: coolguyaroundyou | last post by:
Consider the following codes: class abc { int i; public: abc() : i(0) {} void func() { .....some code....} };
4
7112
by: James Kanze | last post by:
On Nov 18, 5:50 pm, Pete Becker <p...@versatilecoding.comwrote: Has this changed in the latest draft. According to my copy of the standard (version 1998---out of date, I know), "The operand shall be an lvalue or a qualified-id". His expression was &Test("test2"); IMHO, the compiler generated a warning because it was being laxist.
0
8357
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8277
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8803
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8700
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8465
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6158
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4144
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4285
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1910
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.