From: Daniel Mark on
Hello all:

When I compile
const char* msg_to_usr2(void)
{
const int rsp_cnt = 5;

// this is wrong
char usr_msgs[] = "Hello";
return usr_msgs;
}

warning C4172: returning address of local variable or temporary

while the following code is correct.
const char* msg_to_usr2(void)
{
const int rsp_cnt = 5;
// this is correct
char* usr_msgs[] = {"hello"};
return usr_msgs[0];
}

Because the syste has assigned a memeory space to usr_msgs[0] which is used
to store
the memory location of "hello" in heap memory, the program returns the
string without error.

I guess there are some other reasons for it.


May anyone give me some comments?


THank you
-Daniel


From: William DePalo [MVP VC++] on
"Daniel Mark" <daneilmarkhot(a)hotmail.com> wrote in message
news:OGPAP%23MXGHA.4620(a)TK2MSFTNGP04.phx.gbl...
> Hello all:
>
> When I compile
> const char* msg_to_usr2(void)
> {
> const int rsp_cnt = 5;
>
> // this is wrong
> char usr_msgs[] = "Hello";
> return usr_msgs;
> }
>
> warning C4172: returning address of local variable or temporary
>
> while the following code is correct.
> const char* msg_to_usr2(void)
> {
> const int rsp_cnt = 5;
> // this is correct
> char* usr_msgs[] = {"hello"};
> return usr_msgs[0];
> }
>
> Because the syste has assigned a memeory space to usr_msgs[0] which is
> used to store
> the memory location of "hello" in heap memory, the program returns the
> string without error.
>
> I guess there are some other reasons for it.
>
>
> May anyone give me some comments?

In the first snippet, you are trying to return the _address_ of something on
the stack. And as the stack will be "popped" of its local variables on the
return instruction, that's a problem.

In the second snippet, you are returning a single byte to the caller. No
problem here because that byte is copied to the return value passed by the
caller (it fits easily into a register in x86 environment)

Regards,
Will


From: Doug Harrison [MVP] on
On Mon, 10 Apr 2006 13:49:52 -0500, "Daniel Mark"
<daneilmarkhot(a)hotmail.com> wrote:

>Hello all:
>
>When I compile
>const char* msg_to_usr2(void)
>{
> const int rsp_cnt = 5;
>
>// this is wrong
> char usr_msgs[] = "Hello";
> return usr_msgs;
>}
>
>warning C4172: returning address of local variable or temporary

Could be fixed by making usr_msgs static.

>while the following code is correct.
>const char* msg_to_usr2(void)
>{
> const int rsp_cnt = 5;
>// this is correct
> char* usr_msgs[] = {"hello"};
> return usr_msgs[0];
>}
>
>Because the syste has assigned a memeory space to usr_msgs[0] which is used
>to store
>the memory location of "hello" in heap memory, the program returns the
>string without error.
>
>I guess there are some other reasons for it.
>
>
>May anyone give me some comments?

The second one returns the address of a string literal, and string literals
exist throughout a program's lifetime. That's the only reason it works. The
fact that usr_msgs is involved is incidental, as you're returning a copy of
the contents of usr_msgs[0]; that is, the array usr_msgs needn't exist
after the function returns. It would be incorrect if you had written:

char* f()
{
char c;
char* usr_msgs[] = { &c };
return usr_msgs[0]; // Bad
}

This one could be fixed by making "c" static, but again, it doesn't matter
that usr_msgs ceases to exist once the function returns. The problem is
that the local variable "c" has ceased to exist.

--
Doug Harrison
Visual C++ MVP
From: William DePalo [MVP VC++] on
"William DePalo [MVP VC++]" <willd.no.spam(a)mvps.org> wrote in message
news:OvkCzCNXGHA.4768(a)TK2MSFTNGP05.phx.gbl...
> In the second snippet, you are returning a single byte to the caller. No
> problem here because that byte is copied to the return value passed by the
> caller (it fits easily into a register in x86 environment)

Oops. I missed a level of indirection in the second snippet (I read char*
usr_msgs[] = {"hello"}; as char usr_msgs[] = {"hello"}; ). See Doug's reply
for the correct answer.

Mea culpa.

Regards,
Will


From: Daniel Mark on
Hello Doug:

I have figured out those problems by following your comments.

> char* f()
> {
> char c;
> char* usr_msgs[] = { &c };
> return usr_msgs[0]; // Bad
> }
>
> This one could be fixed by making "c" static, but again, it doesn't matter
> that usr_msgs ceases to exist once the function returns. The problem is
> that the local variable "c" has ceased to exist.

I use MS VC6 to compile the above code without warning(pretty strange)
and the output from the screen tells me
that this usage is bad. Originally, I expect MS VC6 could give me some
compile warning.


Many thinks to you!
-Daniel

Also thanks Will!