用代码判断栈的增长方向

对于大部分CPU架构和编译器来说,程序的栈空间增长方向都是向下递减的,然而这也不是一定的。我们可以用一小段简单的C语言代码来判断下栈的增长方向。

栈基本都是用于保存局部变量和传递参数,故要判断栈的增长方向就要从这两个方面入手。第一篇参考资料中给出了各种思路及其可行性分析,很值得看看,此处直接给出结论:

  • 一个函数中的局部变量在栈中的顺序是不定的,或者说是由编译器决定的,故不能通过直接比较两个局部变量的地址来判断栈的增长方向;
  • 函数参数压栈的顺序也是不确定的,虽然一般编译器都是从后向前压栈,然而从前向后也不是绝对不可能;
  • 连续嵌套调用两个函数时,第一个函数的相关数据会先入栈,之后才是它调用的第二个函数,这一点应该是一个通用成立的结论。

综上,要判断栈的增长方向,可以通过函数的嵌套调用来进行判断,更优雅一点的方案是使用递归,得到的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
typedef enum {Upward, Downward} Stack_Dir_t;

Stack_Dir_t detect_stack_dir(char * p) {
char local = 0;
if (p) {
return &local > p ? Upward : Downward;
} else {
return detect_stack_dir(&local);
}
}

int main() {
if (detect_stack_dir(NULL) == Upward)
printf("Stack Growth Upward!\n");
else
printf("Stack Growth Downward!\n");

return 0;
}

在绝大多数平台上,我们得到的结果应该都是Stack Growth Downward!


参考资料:
判断栈和堆的生长方向
栈增长方向与大端/小端问题