问题描述
do{
ys = (ys*ys + 1)%n;
d = egcd(x > y ? x - y : y - x,n,NULL,NULL);
}while(d == 1);
这个循环是使用 gcd 聚合的 Pollard-Rho-Brent 分解算法的一部分。这保证了它会在它出现在更大的程序中的地方终止。然而,y
而不是 ys
的小错误意味着循环永远不会终止,因为 ys
中的更改永远不会反映在 d
中。但是,scan-build
无法识别此问题。最初我认为这是因为它不知道 egcd
是一个纯函数。 (egcd
返回前两个参数的 gcd,如果后两个参数为非空,则将 Bezout 系数输出到后两个参数。)但是,即使我注释掉循环的那一行,d
也不会被修改, scan-build
无法报告无限循环。有没有办法让 scan-build
报告这种错误,或者是否有另一个我可以使用的开源静态分析器?我很惊讶注释掉第二行并没有给出任何警告,我确定我已经看到了类似错误的警告,在 i
和 j
where {{1} 上嵌套 for 循环}} 在两者中都增加,但检查仍然正确。
编辑:i
是什么并不重要。定义是
egcd
但它可能只是 int64_t egcd(int64_t a,int64_t b,int64_t *_t,int64_t *_s){
int64_t r0 = b,r1 = a;
int64_t s0 = 1,s1 = 0;
int64_t t0 = 0,t1 = 1;
while(r1){
int64_t q = r0/r1,t;
t = r1;
r1 = r0 - q*r1;
r0 = t;
t = s1;
s1 = s0 - q*s1;
s0 = t;
t = t1;
t1 = t0 - q*t1;
t0 = t;
}
if(_t){
*_t = t0;
}
if(_s){
*_s = s0;
}
return r0;
}
甚至 #define egcd(a,b,t,s) (a)==(b)?a:1
或者使用它的行可以被注释掉,并且 clang 静态分析器仍然不会将其识别为无限循环。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)