此函数模拟一个函数,该函数返回一个连续上升的值,直到发生溢出为止。就像Arduino中的millis()
函数一样。
为了证明其实现,我需要增加(因此分配)静态变量以保持两次调用之间的状态。但是,调用mock_millis()
的函数仍然应该能够assign \nothing
。
有没有一种方法可以使WP忽略Assigns子句?
static int64_t milliseconds = 0;
/*@ assigns milliseconds;
behavior normal:
assumes milliseconds < INT64_MAX;
ensures \result == \old(milliseconds) + 1;
ensures milliseconds == \old(milliseconds) + 1;
behavior overflow:
assumes milliseconds == INT64_MAX;
ensures \result == 0;
ensures milliseconds == 0;
complete behaviors normal, overflow;
disjoint behaviors normal, overflow;
*/
int64_t mock_millis() {
if (milliseconds < INT64_MAX) {
milliseconds++;
} else {
milliseconds = 0;
}
return milliseconds;
}
我尝试使用重影变量执行此操作,并注意到分配重影变量的函数不能为assigns \nothing
。我认为鬼变量完全独立于程序的实现。有特殊原因吗?
答案 0 :(得分:3)
我假设您的static
变量被称为milliseconds
,而不是现在的microseconds
。
您对鬼变量的假设确实是错误的:鬼代码不应干扰实际代码,反之亦然(请注意,此时Frama-C并未强制执行此操作)。因此,如果将milliseconds
声明为ghost
,则对其的任何分配都应该在ghost
代码内进行。但是从规范的角度来看,这种分配仍然是副作用,需要在assigns
子句中提及。