示例问题要求我们考虑下面的代码并预测函数funct_1
将打印出来的内容:
void func_1(int i, int j) {
printf("i is %d, j is %d\n", i, j);
}
/* ... */
/* somewhere in the code, a call to func_1 */
int i = 30;
func_1(i, i++);
/* ... */
我认为当参数以递增的形式传递时,无法预测编译器何时递增i。然而,解决方案是:
The values in the argument are passed as an attack to the function, hence 'j' receives
a value '30' and then i receives the incremented value which is '31'.
Output: i is 31, j is 30
有人可以解释对某个功能的攻击是什么以及这是怎么发生的?
答案 0 :(得分:3)
预测并非不可能;编译器以确定的方式工作,即使在灰色区域覆盖不良或未被规范覆盖。使用此特定编译器参数从右向左推送,并且在推送右参数后不久发生后增量。
答案 1 :(得分:1)
解决方案一般都是错误的。你是对的;代码的行为是未定义的。在一些编译器上,答案可能是30和31;在其他人身上,它可能是30和30;在其他人身上,可能是31岁和31岁;和其他人可能只是擦除硬盘上的所有文件(因为未定义的未定义行为)。幸运的是,在编译器中,激进的,删除所有的故障痕迹行为相对不太可能。
对于某些特定平台上的某些特定编译器,解决方案可能是正确的。
实际上,我认为j
中的func_1()
不可能得到31 - 但产生30和30的操作序列很容易想象:i
的值是推了两次,然后我增加,然后调用该函数。