无限递归循环编译器是如何处理的
来源:互联网 发布:电视上安装网络机顶盒 编辑:程序博客网 时间:2024/05/16 11:19
不管是C语言还是python ,都支持递归调用,就是函数call 自己,那什么时候,才是个头呢?就是说,什么时候,才跳出循环呢?
consider the following code:
def foo(): foo()try: foo()except RuntimeError: print("RuntimeError")
按道理,这个函数会一直走下去,直到将内存吃完,但这肯定是操作系统不允许的。所以,我们还是会让他走一段时间,然后打印出 RuntimeError。
那具体是如何做到的呢?
这里就要说到一个经常被提到,但又不知道到底是啥的概念, stack, 俗称 栈
坊间流传这样一个说法: inus Torvalds说“Talk is cheap. Show me the code”
接下来,我就用代码挨个说明,背后的实现方式:
void mp_stack_ctrl_init(void) { volatile int stack_dummy; MP_STATE_THREAD(stack_top) = (char*)&stack_dummy; /* * 这个函数,应该说还是设计的很巧妙, stack_dummy 类型为volative, 就是说它的值是随时可以变的 * 第二个,它又是local variable, local variable 刚好就是分配在stack上面的,表达式(char*)&stack_dummy * 各符号的作用依次为 取出地址,拿到值,然后给stack_top (就是保存起来)。注意,这个函数是在程序最开头运行的。 * 就是在程序的最开头,设定一个临界值,栈不能超过这个范围。 */}void mp_stack_set_top(void *top) {/* * 设置top */ MP_STATE_THREAD(stack_top) = top;}mp_uint_t mp_stack_usage(void) { /* * 检查栈用超了没有,即用栈顶地址,减去当前局部变量所拥有有地址。即程序的栈当前已经用了多少内存了 */ // Assumes descending stack volatile int stack_dummy; return MP_STATE_THREAD(stack_top) - (char*)&stack_dummy;}#if MICROPY_STACK_CHECKvoid mp_stack_set_limit(mp_uint_t limit) { /* * 给栈设定一个极限,函数用超了,就抛出异常。比如设为1M。 */ MP_STATE_THREAD(stack_limit) = limit;}void mp_exc_recursion_depth(void) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OverflowError, MP_OBJ_NEW_QSTR(MP_QSTR_maximum_space_recursion_space_depth_space_exceeded)));}void mp_stack_check(void) { /* * 如果用掉的内存,大于所指定的极限值,即调用抛出异常胡handler. */ if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) { mp_exc_recursion_depth(); }}#endif // MICROPY_STACK_CHECK
写到这里,大家可能会想到一个问题,关于对stack 使用的情况,什么时候检查呢?
答案就是每次调用obj 的成员函数之前,做一次检查。如果指定的栈用完了,后面的程序不跑了。
阅读全文
0 0
- 无限递归循环编译器是如何处理的
- 【链接】C++编译器是如何实现异常处理的
- 编译器是如何运作的
- 编译器是如何工作的?
- .Net MVC无限循环或无限递归
- 目录无限循环递归是怎么回事?
- 死循环与无限递归
- jstree无限循环递归的后台相关实现
- 无限极分类这个是不用递归查询的
- 判断一个分数是否是无限循环的小数.
- printf("%d,%d,%d,%d\n",i++,--i,++i,i++);编译器是如何处理的。
- 编译器内部的秘密--微软的编译器是如何解析
- 递归处理List集合【无限级分类的实现】
- Gson转换无限循环处理
- 编译器是如何进行宏替换的?
- 【编译原理】编译器是如何工作的?
- 编译器是如何工作的?(转)
- CRM中工作流出现无限循环的处理办法
- 《日本语能力测试阶梯导学读解专训N2》
- 【笔记】深入理解 java 虚拟机---GC.
- pstree命令乱码问题
- jsp九大隐含对象
- MySQL索引和查询优化
- 无限递归循环编译器是如何处理的
- HashMap根据value获取key
- hrbust 又是Fibonacci (矩阵快速幂)
- 博客第一天
- JavaScript浏览器端文本转语音
- jQuery实现瀑布流
- js屏蔽鼠标右键默认事件以实现自定义菜单
- RocketMQ 客户端最佳实践
- 顺序表的实现(头插,头删尾插,尾删)