ACSL 可以表示应隐藏分配吗?
Can ACSL denote that an assignment should be hidden?
此函数模拟了一个 returns 持续上升值直到发生溢出的函数。就像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
。我认为幽灵变量完全独立于程序实现。这有什么特殊原因吗?
我假设您的 static
变量应该被称为 milliseconds
而不是现在的 microseconds
。
您关于幽灵变量的假设确实是错误的:幽灵代码不应干扰真实代码,反之亦然(请注意,此时 Frama-C 并未强制执行此操作)。因此,如果您将 milliseconds
声明为 ghost
,对它的任何赋值都应该发生在 ghost
代码中。但是从规范的角度来看,这样的赋值仍然是副作用,需要在 assigns
子句中提及。
此函数模拟了一个 returns 持续上升值直到发生溢出的函数。就像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
。我认为幽灵变量完全独立于程序实现。这有什么特殊原因吗?
我假设您的 static
变量应该被称为 milliseconds
而不是现在的 microseconds
。
您关于幽灵变量的假设确实是错误的:幽灵代码不应干扰真实代码,反之亦然(请注意,此时 Frama-C 并未强制执行此操作)。因此,如果您将 milliseconds
声明为 ghost
,对它的任何赋值都应该发生在 ghost
代码中。但是从规范的角度来看,这样的赋值仍然是副作用,需要在 assigns
子句中提及。