Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Problem "taking address of temporary"

Reply
Thread Tools

Problem "taking address of temporary"

 
 
Andy Gibbs
Guest
Posts: n/a
 
      11-18-2008
Hello,

I have a problem with the following example code:

#include <stdio.h>

class Test
{
public:
Test(char* str)
{
printf("ctor\n");
_str = str;
}

~Test()
{
printf("dtor\n");
}

char* _str;
};

void Function(const Test* const t)
{
if (t) printf("str=%s\n", t->_str);
else printf("null\n");
}

int main(int argc, char *argv[])
{
printf("test1:\n");
{ Test t("test1"); Function(&t); }

printf("test2:\n");
Function(&Test("test2"));

printf("test3:\n");
Function(0);
}


The problem comes in the line "Function(&Test("test2"));" with the
warning "taking address of temporary". I am using GCC 4.1.2. However, the
code runs as expected with the following output:

test1:
ctor
str=test1
dtor
test2:
ctor
str=test2
dtor
test3
null

The code above demonstrates that the Test object is not destroyed until
after Function is called, so I cannot see why the compiler complains about
this. However, for my actual application, this particular syntax is what I
require in order to keep the code at its most legible, and so I really hope
to find a solution to this warning.

Is there some way I should alter the signature of Function to stop the
warning? Is there a compiler option to ignore this specific warning (e.g.
a #pragma or something)?

Thanks for any help!

Andy


 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      11-18-2008
On Nov 18, 5:50 pm, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-11-18 10:52:48 -0500, Andy Gibbs <andyg1...@hotmail.co.uk> said:
> > The problem comes in the line "Function(&Test("test2"));"
> > with the warning "taking address of temporary". I am using
> > GCC 4.1.2. However, the code runs as expected with the
> > following output:


> > test1:
> > ctor
> > str=test1
> > dtor
> > test2:
> > ctor
> > str=test2
> > dtor
> > test3
> > null


> > The code above demonstrates that the Test object is not
> > destroyed until after Function is called, so I cannot see
> > why the compiler complains about this.


> The compiler warns about it because the code takes the address
> of a temporary, although there's nothing inherently wrong with
> doing that.


Has this changed in the latest draft. According to my copy of
the standard (version 1998---out of date, I know), "The
operand [of the unary & operator] shall be an lvalue or a
qualified-id". His expression was &Test("test2"); IMHO, the
compiler generated a warning because it was being laxist.

If I compile his code with Sun CC, I get:
"addrtemp.cc", line 34: Warning, badargtypel2w: String literal
converted to char* in formal argument str in call to Test::Test
(char*).
"addrtemp.cc", line 37: Warning, badargtypel2w: String literal
converted to char* in formal argument str in call to Test::Test
(char*).
"addrtemp.cc", line 37: Error, wantvarname: The "&" operator can
only be applied to a variable or other l-value.
Which is what I'd expect from a good compiler. Curiously
enough, g++ only generates says:
addrtemp.cc: In function 'int main(int, char**)':
addrtemp.cc:37: warning: taking address of temporary
even with -std=c++98 -pedantic (I'd call this a bug), and VC++
doesn't say anything.

> If you misuse the result you can get in trouble. Apparently
> the writers of your compiler thnk that you can't be trusted to
> use that address without screwing up.


Apparently, the writers of his compiler don't care about the
standard. (Nothing new there.) And it's the members of the
stadnards committee who think you can't be trusted. (Or just
wanted to remain compatible with C in this respect.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
 
 
 
Andrey Tarasevich
Guest
Posts: n/a
 
      11-18-2008
Andy Gibbs wrote:
>
> The problem comes in the line "Function(&Test("test2"));" with the
> warning "taking address of temporary". I am using GCC 4.1.2. However, the
> code runs as expected with the following output:
>
> test1:
> ctor
> str=test1
> dtor
> test2:
> ctor
> str=test2
> dtor
> test3
> null
>
> The code above demonstrates that the Test object is not destroyed until
> after Function is called, so I cannot see why the compiler complains about
> this.


The compiler complains about this because it is _illegal_ in C++ to take
the address of a temporary. Temporary objects are not lvalues in C++,
which means that unary '&' is not applicable to them. Your program is
ill-formed, meaning that the attempt to take address is what is normally
called an "error". Your compiler issues a mere "warning" simply because
it decided to allow you to take the address as a compiler-specific
language extension, but at the same time wants to stick with the
standard requirement to issue a "diagnostic message" in case of an
ill-formed program.

Also, an experiment with the code doesn't really "demonstrate" anything
reliably.

> However, for my actual application, this particular syntax is what I
> require in order to keep the code at its most legible, and so I really hope
> to find a solution to this warning.


I'd recommend you to stick with well-formed code. I.e. stop trying to
get the address of a temporary.

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      11-18-2008
Victor Bazarov wrote:
>
> There is an inherent controversy around this. Example:
>
> struct Foo {
> Foo(int) {}
> Foo& that() { return *this; }
> };
>
> int main() {
> Foo(42); // expression that yields an rvalue
> Foo(42).that(); // expression that is an lvalue
> }
>
> How would you explain that? You can't avoid being "laxist" with the
> language that contains such pearls.
> ...


There's an inherent controversy around everything, if you dig deep
enough. Your example is not really different from, say

const int* addr(const int& i) { return &i; }

int main() {
const int* p = addr(42);
}

You think this is a "pearl"? I'd say this is just a necessary evil one
has to remember about.

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      11-18-2008
On Nov 18, 6:53*pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> James Kanze wrote:


[...]
> >> The compiler warns about it because the code takes the
> >> address of a temporary, although there's nothing inherently
> >> wrong with doing that.


> > Has this changed in the latest draft. *According to my copy of
> > the standard (version 1998---out of date, I know), "The
> > operand [of the unary & operator] shall be an lvalue or a
> > qualified-id". *His expression was &Test("test2"); IMHO, the
> > compiler generated a warning because it was being laxist.
> > [..]


> There is an inherent controversy around this. *Example:


> * * struct Foo {
> * * * * Foo(int) {}
> * * * * Foo& that() { return *this; }
> * * };


> * * int main() {
> * * * *Foo(42); * * * *// expression that yields an rvalue
> * * * *Foo(42).that(); // expression that is an lvalue
> * * }


> How would you explain that?


I wouldn't try to. But the language standard defines a
concept of lvalue and rvalue, or at least insists that they
exist, that certain expressions return lvalues, others rvalues,
and that certain operators require lvalues, others rvalues (and
that there is an lvalue to rvalue conversion---so that in
something like i=j, where both i and j have type int, there is
an implicit conversion involved). The language says that the
expression Test("test1") is an rvalue, and it says that unary &
requires an lvalue, and so be it.

> You can't avoid being "laxist" with the language that contains
> such pearls.


Such "pearls" are probably inevitable as soon as you try to
maintain the distinction between lvalues and rvalues, and also
have real objects. (At one point, I actually suggested that we
drop the concept of lvalue/rvalue completely, and simply state
that all temporaries were considered const. This would have
allowed things like &3, with type int const, but after all, we
allow this indirectly already, if you bind 3 to a const
reference, and then take its address.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Andy Gibbs
Guest
Posts: n/a
 
      11-19-2008
Andy Gibbs wrote:

> Hello,
>
> I have a problem with the following example code:
>
> ...


Hello all,

Thanks for all your comments and recommendations!

Cheers
Andy
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
VPN with DMZ IP address NETed to LAN IP address!!! route-map!!! examples20001@gmail.com Cisco 0 02-07-2006 04:05 PM
PIX Firewall MAC address VPN IP address Julian Dragut Cisco 1 02-07-2006 07:57 AM
obtaining the IP ADDRESS of an IP POHNE by its MAC ADDRESS ProgDario Cisco 17 05-06-2005 02:32 PM
Routing to public IP of NAT address from internal NAT address Andrew Albert Cisco 1 02-08-2005 07:05 PM
Re: Hide Address Bar or Encrypt Address?? avnrao ASP .Net 1 05-04-2004 03:46 PM



Advertisments