E. Robert Tisdale said:
pmm said:
Is there any way to know in which direction stack grows?
A stack always grows upward. Unfortunately,
neither your computer nor your compiler knows up from down.
The C programming language doesn't know anything about stacks.
It only knows about "automatic storage"
which is usually implemented on the program stack.
For the typical implementation,
you can think of program memory being organized
as a contiguous sequence of [virtual] memory addresses
starting with 00000000 at the top and
ending with FFFFFFFF at the bottom.
The bottom of the program stack
is somewhere near the bottom of [virtual] memory
and grows upward into free storage.
The "stack pointer" is
"decremented" when you "push" objects onto the program stack and
"incremented" when you "pop" objects off of the program stack.
This description assumes that the stack grows toward low addresses
(when the addresses are interpreted as integers). (It also assumes
32-bit addresses.) It's entirely possible for the stack to grow
toward high addresses. I don't know how common this is in real-world
systems -- and since I don't program in assembly or machine language,
I don't need to know. If I did know, there would be no way to use
that knowledge in a portable program; it's unlikely it would be useful
even in a non-portable program.
If you're curious about how some particular system does this, here's a
program that *might* be helpful:
#include <stdio.h>
void func(int *outer_addr)
{
int inner_obj;
printf("Object in main() is at [%p]\n", (void*)outer_addr);
printf("Object in func() is at [%p]\n", (void*)&inner_obj);
#ifdef ALLOW_UNDEFINED_BEHAVIOR
if (&inner_obj > outer_addr) {
printf("Stack appears to grow toward high addresses\n");
}
else {
printf("Stack appears to grow toward low addresses\n");
}
#endif
}
int main(void)
{
int outer_obj;
func(&outer_obj);
return 0;
}
Since inner_obj is "higher" on the stack than outer_obj, examining
their relative addresses can tell you which way the stack grows *if*
that's a meaningful question in the first place. On many systems,
printf's "%p" format will show you a numerically meaningful
representation of a pointer; if so, you can compare them by examining
the output.
Using the "<" operator to compare two pointers that don't point into
the same object (or just past the end of it) invokes undefined
behavior. It can legally return a value that depends on the phase of
the moon, or it can crash your entire system. On many systems, such a
comparison does give a result that's meaningful for the underlying
system (though not necessarily meaningful in C terms). On such
systems, the above program with the macro ALLOW_UNDEFINED_BEHAVIOR
defined will probably tell you which way the stack grows.
Keep in mind that there's really nothing meaningful you can do with
this information, though of course there's nothing wrong with wanting
to satisfy idle curiosity.
"Which way does the stack grow" is actually an excellent question, but
knowing the answer isn't nearly as useful as knowing why there's not
really any meaningful answer.