我想不出任何想法来证明foo
的assigns子句。我尝试了assigns var;
,因为foo()
间接修改了全局var
变量,但是它不起作用。有没有一种方法可以获取本地assigns
的{{1}}子句或从p
返回的位置?这是代码:
a()
frama-c命令:
int var;
//@ assigns \nothing;
int *a(){
return &var;
}
//@ assigns *p;
void b(int* p){
*p = 1;
}
//@ assigns \nothing;
void foo(){
int *p = a();
b(p);
}
//@ assigns var;
void main(){
var = 0;
foo();
return;
}
frama-c -wp test.c
答案 0 :(得分:1)
如您所料,foo
是确实分配了一些东西,而assigns \nothing
是此函数的无效子句。正确的子句确实是assigns var
。在assigns
子句中,您必须列出所有已修改的全局变量,以及所有在调用者本地且可以通过形式引用的变量。
现在,为什么不使用assigns var
进行变体证明?好吧,按照foo
的说法,WP无法猜测p
指向的位置,因为它无法知道它实际上等于&a
。您必须将此信息添加到功能a
的规范中。通过此修改,证明是即时的。
完整代码:
int var;
/*@ assigns \nothing;
ensures \result == &var; */
int *a(){
return &var;
}
//@ assigns *p;
void b(int* p){
*p = 1;
}
//@ assigns var;
void foo(){
int *p = a();
b(p);
}
//@ assigns var;
void main(){
var = 0;
foo();
return;
}