Consider the following function:
void f(char *x)
{
*x = 1 ;
}
char g(void)
{
char a[16] ;
char *p ;
p =&a[0] ;
f(p) ;
return a[0] ;
}
My understanding is that g() should return 1 because the pointer
passed to f() corresponds to a memory region that, although local to g(),
is still in scope when g() gets invoked. Is this correct?
Close. Others have already pointed out the f()/g() confusion,
but I haven't seen mention of another issue: It's not the "scope"
of the array `a' that matters, but its "storage duration."
The "scope" of an identifier is the portion of a source program
in which the identifier is associated with a specific variable (or
function, or type, or label, or whatever the identified thing is).
The "scope" of `a' begins at its declaration and extends to the end
of the containing block; in this case, to the `}' at the end of g().
The scope of `a' does not include f() or any part of it; `a' is *not*
in scope inside f().
The "storage duration" (or "lifetime") of an object is the portion
of the program's execution time during which memory is allocated for
the object. In your code, storage is allocated for the object known
as `a' when g() begins executing, and remains allocated until g()
returns. And that's what f() cares about: Not whether it can use the
identifier `a' (it cannot, because `a' is not in scope), but whether
its parameter `p' is pointing to an object that still exists (it does,
because g() has not yet returned and released its objects' memory).
It is easy to confuse "scope" and "storage duration" for auto
variables, because the `}' that ends the scope often marks the point
at which execution leaves the block, and hence the point at which
the allocated objects are discarded. But if you think about it a bit
you'll see that the common end-point means very little. After all,
"scope" is a lexical property covering a span of source code characters,
while "storage duration" is an execution property covering a span of
time -- the two notions don't even refer to the same dimension.
If you're comfortable with the notion of recursion, this may become
clear if you consider a variable `x' inside a function that is called
recursively. There's clearly only one identifier `x' and one scope
associated with it, yet the `x' refers to several different data
objects with different storage durations. Hence, "scope" and "storage
duration" cannot be the same, or even similar.