编译器为布尔表达式生成跳转式中间代码时,某些条件跳转的目标基本块尚未生成。回填技术的主要作用是()。
单遍生成中间代码时,条件跳转指令可能先出现,而目标基本块的入口地址要到后面才知道。编译器先把这些未定目标指令的编号组织成 true list 或 false list,待目标地址确定后,用 backpatch 一次性填入。
选项分析
错误。回填发生在编译生成中间代码阶段,不是运行时自修改源代码。
错误。条件跳转仍保留真假选择,回填只补目标地址。
错误。短路布尔代码依靠控制流选择分支,不需要先执行两个分支。
正确。回填先挂起未知目标,再在地址确定时补齐跳转字段。
本题为什么容易错
“回填”听起来像程序运行时补数据,容易和动态链接、自修改代码混淆。它本质是编译器在尚不知道标签地址时留下待办项,随后完成控制流连接。
简短答案
布尔表达式中间代码为什么要使用回填技术,正确答案是 D(先记录目标未定的跳转指令链表,目标确定后统一填写地址)。单遍生成中间代码时,条件跳转指令可能先出现,而目标基本块的入口地址要到后面才知道。编译器先把这些未定目标指令的编号组织成 true list 或 false list,待目标地址确定后,用 backpatch 一次性填入。
易混淆概念对比表
| 概念 | 本题判断 | 区别要点 | 记忆提示 |
|---|---|---|---|
| 在程序运行时修改源代码中的条件表达式 | 本题干扰项 | 错误。回填发生在编译生成中间代码阶段,不是运行时自修改源代码。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
| 把所有条件跳转改成无条件跳转 | 本题干扰项 | 错误。条件跳转仍保留真假选择,回填只补目标地址。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
| 提前执行真假两个分支,再选择保留结果 | 本题干扰项 | 错误。短路布尔代码依靠控制流选择分支,不需要先执行两个分支。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
| 先记录目标未定的跳转指令链表,目标确定后统一填写地址 | 本题正确答案 | 正确。回填先挂起未知目标,再在地址确定时补齐跳转字段。 | 看到题干核心场景时优先联想到它 |
本题易混淆选项怎么区分
- 在程序运行时修改源代码中的条件表达式:错误。回填发生在编译生成中间代码阶段,不是运行时自修改源代码。
- 把所有条件跳转改成无条件跳转:错误。条件跳转仍保留真假选择,回填只补目标地址。
- 提前执行真假两个分支,再选择保留结果:错误。短路布尔代码依靠控制流选择分支,不需要先执行两个分支。
知识点详解
控制流语句和短路布尔表达式常包含向前跳转。单遍翻译时,目标语句尚未生成,编译器无法立即填写跳转地址,于是用链表记录所有待定指令。目标入口确定后,backpatch 将同一链表中的地址字段统一填为该入口。对 E1 and E2,E1 的真出口通常回填到 E2 入口;对 E1 or E2,E1 的假出口通常回填到 E2 入口,这正体现短路求值。
备考速记
地址未知先挂账,入口确定再沿链表统一补上。
短路求值在短路求值场景中的作用
短路求值在本题中的核心价值,是解决“编译器为布尔表达式生成跳转式中间代码时,某些条件跳转的目标基本块尚未生成。回填技术的主要作用是()”这个场景问题。复习时不要只背选项名称,还要理解它为什么适用于该场景,以及它能解决哪类安全、流程或管理问题。
同类题怎么考
- 给出布尔表达式,判断 true list 和 false list 如何合并与回填。
- 根据 if、if-else、while 的中间代码确定某链表回填到哪个入口。
- 结合短路求值解释为什么无需先计算完整布尔值。
短路求值在软件设计师软考中的考法
软考选择题通常不会只考概念定义,还会把短路求值放到短路求值场景中,要求判断它的作用、适用范围或与相近概念的区别。遇到这类题时,先抓住题干中的业务场景,再看哪个选项最能解决该场景下的核心问题。
解题思路
把它想成老师先写“答错的同学去第____页订正”,页码还没排出来,就把所有空格位置记在一张清单上。等订正页确定,再沿清单一次填完。回填改的是编译期间的跳转目标,不是程序跑起来以后去改源代码。
考点定位
回填解决向前跳转目标暂时未知的问题:makelist 创建链表,merge 合并链表,backpatch 将链表中指令的目标字段统一填写为已知地址。
易错提醒
- 把 true list 和 false list 当成布尔值数组,而不是待填目标的跳转指令编号集合。
- 认为回填会改变条件判断本身,实际上它只补跳转去向。
- 忽略短路求值中不同布尔运算对真假链表的合并方式不同。
备考提示
- 画两条虚线:条件为真去哪、为假去哪;目标未知时把指令编号挂到对应链表。
- 复习 makelist、merge、backpatch 三个操作时,配合 if 和 while 的控制流图理解。
你可能还想了解
- true list 和 false list 保存的是什么?
- makelist、merge、backpatch 分别做什么?
- 回填技术与短路求值有什么关系?
- if-else 中哪些跳转目标需要延后回填?
本文小结
回填用于处理编译期间尚未确定目标地址的向前跳转。先把待填指令编号放入真假出口链表,等目标基本块入口确定后,再统一补齐跳转地址。