A simple way to determine the direction of stack growth is to compare the address of a function parameter with the address of a local variable in the function. Of course, the main difficulty here is to avoid compiler optimization, such as register variables, function inlining, and so on. So, the first attempt may look like the following function:
void stack_growth(char *function_parameter) { char local; if (&local > function_parameter) printf("up
"); else printf("down
");}
The above code can be called as follows:
char c = 'c'; stack_growth(&c);
This example can be improved by using volatile modifiers and changing scalar variables into arrays:
void stack_growth(volatile char *function_parameter) { volatile char local [64]; if (&local [63] > function_parameter) printf("up
"); else printf("down
");}
and calling this function as follows:
volatile char c[64]; stack_growth(&c[63]);
Further improvements can be made using variable length parameter lists (va_arg), recursive calls that compare the address of a local variable in different recursive iterations (in this case, it is important to avoid tail recursion elimination), and so on. However, there is no portable, standard-compliant way to do this because:
- Comparison of pointers is guaranteed valid only when the pointers refer to objects in the same array or to the location one past the end of the array.
- The stack organization, as pointed out by W. Richard Stevens and others, may have different forms, depending on the build-in hardware support and other factors. Therefore, the best way to determine the direction of stack growth is to check the documentation and code it as a constant.
It is also possible to find out the direction of stack growth by noting that it is the opposite of the heap growth direction (stack and heap usually grow towards each other), but this method is not very reliable either. For example, take the following code:
char *m1 = (char *)malloc(2);char *m2 = (char *)malloc(2);
Whether m1 will be greater than m2 or not depends heavily on the memory allocation method.