returning stack variables

G

Guray Acar

Hi,

please consider the code:

int myFunction(void)
{ int x=0;

return x;
}

Now, my friend claimed that the code above is erroneous
because the int variable x is created in the stack. The function
returns the address of x in the stack. But the addresses in the
stack may change outside the function myFunction.

I found his argument quite plausible. However, I have seen
so many functions like the one above. I have written functions
doing what myFunction does, and they worked without error
for long time.

Can anyone clarify this issue ? TIA..

Regards

Guray Acar
 
J

Joona I Palaste

Guray scribbled the following:
please consider the code:
int myFunction(void)
{ int x=0;
return x;
}
Now, my friend claimed that the code above is erroneous
because the int variable x is created in the stack. The function
returns the address of x in the stack. But the addresses in the
stack may change outside the function myFunction.

Your friend is talking out of his tailpipe. He's just plain wrong.
The function doesn't return the address of *ANYTHING AT ALL*. It
returns the *VALUE* of x, which is a separate concept from x itself.
Your function is completely OK, legal, valid, kosher, all-singing,
all-dancing and hunky dory.
I found his argument quite plausible. However, I have seen
so many functions like the one above. I have written functions
doing what myFunction does, and they worked without error
for long time.

His argument would be plausible *IF* you were returning the address
of x. But you aren't, so his argument dissolves like O'Boy cocoa
powder into a glass of cold milk and you win your argument.
*THIS* kind of code would be illegal, because of the reason your
friend gives:

int *myFunction(void) {
int x=0;
return &x;
}

but that's a whole different kettle of fish.
Can anyone clarify this issue ? TIA..

The issue is that there is no address returning in the function, only
value returning, and returning values of any variables whatsoever is
safe.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"The large yellow ships hung in the sky in exactly the same way that bricks
don't."
- Douglas Adams
 
J

Joona I Palaste

Joona I Palaste said:
Guray scribbled the following:
Your friend is talking out of his tailpipe. He's just plain wrong.
The function doesn't return the address of *ANYTHING AT ALL*. It
returns the *VALUE* of x, which is a separate concept from x itself.
Your function is completely OK, legal, valid, kosher, all-singing,
all-dancing and hunky dory.
His argument would be plausible *IF* you were returning the address
of x. But you aren't, so his argument dissolves like O'Boy cocoa
powder into a glass of cold milk and you win your argument.
*THIS* kind of code would be illegal, because of the reason your
friend gives:
int *myFunction(void) {
int x=0;
return &x;
}
but that's a whole different kettle of fish.
The issue is that there is no address returning in the function, only
value returning, and returning values of any variables whatsoever is
safe.

....as long as those values are scalars, addresses of static or global
variables, or addresses passed in to the function, that is. Not just
any old values. This kind of function is still illegal:

int *myFunction(void) {
int x=0;
int *y=&x;
return y;
}

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"B-but Angus! You're a dragon!"
- Mickey Mouse
 
E

Emmanuel Delahaye

please consider the code:

int myFunction(void)
{ int x=0;

return x;
}

Sounds good to me.
Now, my friend claimed that the code above is erroneous
because the int variable x is created in the stack. The function

Say, 'in the automatic memory'.
returns the address of x in the stack. But the addresses in the

No. This function is not returning any address, but a value. It's just fine.
stack may change outside the function myFunction.

This is misleading. The point is that the address of an automatic variable is
only valid in the block it was defined. Period. Out of the block, no hope.
I found his argument quite plausible. However, I have seen
so many functions like the one above. I have written functions
doing what myFunction does, and they worked without error
for long time.

/This/ is bad:

int *myFunction(void)
{
int x = 0;

return &x;
}

Don't do that. Never.
 
K

Keith Thompson

Guray Acar writes:
[...]
int myFunction(void)
{ int x=0;

return x;
}

Now, my friend claimed that the code above is erroneous
because the int variable x is created in the stack. The function
returns the address of x in the stack. But the addresses in the
stack may change outside the function myFunction.

As others have pointed out, your friend is mistaken; there's nothing
wrong with the above code.

But here's something that looks similar, but will cause the kind of
problem your friend warned you about:

char *myFunction(void)
{
char s[] = "hello";
return s;
}

Despite the similar appearance, the return statement here really is
returning the address of s not its value. That's because "s" is
declared as an array, and any reference to the name of an array (other
than as an operand of the sizeof and "&" operators) "decays" to the
address of the array's first element.

(Note that this decay doesn't happen for struct and union types.)
 
J

Jason Xie

But here's something that looks similar, but will cause the kind of
problem your friend warned you about:

char *myFunction(void)
{
char s[] = "hello";
return s;
}

I think the above is erroneous too, how about change it as this:
char *myFunction(void)
{
const char s[] = "hello";
return s;
}
 
J

Joona I Palaste

Jason Xie <[email protected]> scribbled the following:


But here's something that looks similar, but will cause the kind of
problem your friend warned you about:

char *myFunction(void)
{
char s[] = "hello";
return s;
}
I think the above is erroneous too, how about change it as this:
char *myFunction(void)
{
const char s[] = "hello";
return s;
}

This should cause the same problem. This, however, is fine:

char *myFunction(void)
{
char *s = "hello";
return s;
}

as long as you do not try to modify the returned string.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"Immanuel Kant but Genghis Khan."
- The Official Graffitist's Handbook
 
G

Giuseppe

Guray Acar writes:
[...]
int myFunction(void)
{ int x=0;

return x;
}

Now, my friend claimed that the code above is erroneous
because the int variable x is created in the stack. The function
returns the address of x in the stack. But the addresses in the
stack may change outside the function myFunction.

As others have pointed out, your friend is mistaken; there's nothing
wrong with the above code.

But here's something that looks similar, but will cause the kind of
problem your friend warned you about:

char *myFunction(void)
{
char s[] = "hello";
return s;
}

Despite the similar appearance, the return statement here really is
returning the address of s not its value. That's because "s" is
declared as an array, and any reference to the name of an array (other
than as an operand of the sizeof and "&" operators) "decays" to the
address of the array's first element.

(Note that this decay doesn't happen for struct and union types.)

char *myFunction(void)
{static char s[] = "hello";
return s;
}

is this ok?
 
N

Nick Austin

char *myFunction(void)
{static char s[] = "hello";
return s;
}

is this ok?

Yes.

But this is one instance where you may want to declare the
return type as const char * to avoid someone writing:

myFunction()[0] = 'H';

Nick.
 
R

Richard Heathfield

No. You got it wrong.

How on earth do you know that?
Your friend claimed that

int& myFunction(void) {
int x = 0;
return x;
}

returns a reference to local variable x
which no longer exists when the thread of execution
returns from function myFunction.

The OP's code at least had the merit of being legal C. Your code is not
legal C. No surprise there.
 
E

E. Robert Tisdale

Richard said:
The OP's code at least had the merit of being legal C.
Your code is not legal C. No surprise there.

No.
But it *is* perfectly legal C++.
Guray posted to the wrong newsgroup as well.
 
R

Richard Heathfield

E. Robert Tisdale said:
No.
But it *is* perfectly legal C++.

This is comp.lang.c, not comp.lang.c++.
Guray posted to the wrong newsgroup as well.

He posted C code to a C newsgroup, and asked a topical question about that
code. You, on the other hand, posted C++ code to a C newsgroup.

It seems to me that it's /you/ who posted to the wrong newsgroup.
 
D

Dik T. Winter

> Richard Heathfield wrote:
>
> > [Guray] posted C code to a C newsgroup
> > and asked a topical question about that code.
>
> Guray posted C++ code to the comp.lang.c newsgroup
> which was similar to C++ code that has the problem
> which Guray's friend was explaining to him.

This was the original code:
> int myFunction(void)
> { int x=0;
>
> return x;
> }

what part of it is not C?
 

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,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top