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 子句中提及。