Как вы уже догадались, 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;
}