Accessing data from another function

S

subhajitdey.m.sc

In the code below:

int *check(int a){
int b,*s;
b=a;
s=&b;
return s;
}
int main(){
int *a,x;
a=check(10);
x=*a;
printf("%d",x);
}


shouldn't there be some sort of error (or garbage value) when I access the address of the local variable in 'check'?
 
R

Rui Maciel

In the code below:

int *check(int a){
int b,*s;
b=a;
s=&b;
return s;
}
int main(){
int *a,x;
a=check(10);
x=*a;
printf("%d",x);
}


shouldn't there be some sort of error (or garbage value) when I access the
address of the local variable in 'check'?

Your code refers to an object outside of its lifetime, which is a behaviour
that was intentionally left undefined in the standard, and regarding which
the standard imposes no requirements.

Having said that, it would be nice if compilers at least threw a warning
about that, but I suspect that catching this sort of problem is no easy
task.


Rui Maciel
 
J

James Kuyper

In the code below:

int *check(int a){
int b,*s;
b=a;
s=&b;
return s;
}
int main(){
int *a,x;
a=check(10);
x=*a;
printf("%d",x);
}


shouldn't there be some sort of error (or garbage value) when I access the address of the local variable in 'check'?

No, error messages are required only when there's a syntax error, a
constraint violation, or one of the few other explicit requirements for
a diagnostic applies. None of them apply here.

In this case the behavior of the code is simply undefined, which means
that there's no wrong way for the compiler to handle it. In particular,
it's permissible for the above code to print "10", and give no
indication how seriously flawed it is. It's even fairly plausible that
it might do so: the life time of 'b' is already over by the time that
this code executes "x = *a", but it's quite likely that the memory 'b'
was stored in still exists, and still contains the last value that was
stored in 'b'.
 
J

Joe Pfeiffer

In the code below:

int *check(int a){
int b,*s;
b=a;
s=&b;
return s;
}
int main(){
int *a,x;
a=check(10);
x=*a;
printf("%d",x);
}


shouldn't there be some sort of error (or garbage value) when I access
the address of the local variable in 'check'?

No. There is no requirement for C to check for this sort of bug, and
typical implementations don't.
 
B

Ben Bacarisse

In the code below:

int *check(int a){
int b,*s;
b=a;
s=&b;
return s;
}
int main(){
int *a,x;
a=check(10);
x=*a;
printf("%d",x);
}


shouldn't there be some sort of error (or garbage value) when I access
the address of the local variable in 'check'?

It would be good if there were a diagnostic form the compiler, but it's
not obliged to do so and, in general, this is a situation that can't be
checked for. If you simplify your code, you do get a warning from gcc:

x.c: In function ‘check’:
x.c:5:6: warning: function returns address of local variable [enabled by default]

from:

#include <stdio.h>

int *check(int a) {
int b = a;
return &b;
}

int main(void) {
printf("%d\n", *check(10));
}

but as you can see, even assignig that value to another local makes gcc
miss it.

BTW, you need to declare printf. And you are getting a "garbage
value" -- it just happens to be confusing garbage!
 
K

Kaz Kylheku

Your code refers to an object outside of its lifetime, which is a behaviour
that was intentionally left undefined in the standard, and regarding which
the standard imposes no requirements.

Having said that, it would be nice if compilers at least threw a warning
about that, but I suspect that catching this sort of problem is no easy
task.

In terms of run-time efficiency, it is proably cheaper just to make it work
than to catch violations. That is to say, allow these local objects
to persists while they are reachable.

The reasoning is that if you want to be able to detect all abuses like
this at run time, then for each local object whose address might escape
from the function, you have to record that address in some permanent "bad
pointer" database, and not reuse that address for any newly created object.

So that this database doesn't run you out of memory, you will need garbage
collection to discover those bad pointers that no longer occur in the program's
state and can be purged.

So you have GC, and you have costly run-time checks guarding the uses
of pointers: two sources of performance hits.

But once you let those object persist without being reused, and you
have GC, then you just might as well let those pointers be valid
and dispense with the run-time checks.

There is nothing "morally" wrong with using an object that was created in a
function that returned, and decriminalization of activities that are not
actually wrong is usually cheaper than enforcement. :)
 
K

Keith Thompson

In the code below:

int *check(int a){
int b,*s;
b=a;
s=&b;
return s;
}
int main(){
int *a,x;
a=check(10);
x=*a;
printf("%d",x);
}


shouldn't there be some sort of error (or garbage value) when I access
the address of the local variable in 'check'?

You *are* getting a garbage value. It just happens to be 10. (At
least, I presume that's what you're seeing; you didn't actually say.)

When I compile your program (after making a couple of small fixes) with
"gcc", I get 10. When I use "gcc -O1", I get -1075723044. When I use
"gcc -O2" or "gcc -O3", I get 0.

A few other things:

You need to add "#include <stdio.h>" to the top of your program so that
the declaration of printf is visible. (Your compiler *should* have
warned you about that; if it didn't, find out how to increase its
warning level.)

You should have a newline at the end of your output:

printf("%d\n", x);

"int main()" should probably be "int main(void)" (this is a very minor
point).

As a matter of style, a bit of whitespace would make your code more
readable.
 

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,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top