On arrays vs. pointer, the ACSL way
Virgile Prevosto - 31st Jul 2012Some time ago, we saw that in C arrays and pointers have some subtle differences. A facetious colleague just remarked that this is also the case in ACSL especially if you use the \at(e L)
construction which basically says that e
is supposed to be evaluated in the state when the program reached label L
for the last time. For instance let us consider the following function:
int t[10]; void f() { int* p = t; int i = 4; L0: t[i++] = 4; L1: t[i--] = 5; L2: t[i++] = 6; return; }
Can you decide which of the following assertions hold just before f
returns?
assert \at(t[\at(i L0)] L1) == 4;
assert \at(t L1)[\at(i L0)] == 4;
assert \at(p[\at(i L0)] L1) == 4;
assert \at(p L1)[\at(i L0)] == 4;
Answers
/*@ assert \at(t[\at(i L0)] L1) == 4; */
This assertion is true: namely i
is equal to 4
in L0
so that we're evaluating t[4]
in L1
which is indeed equal to 4
.
/*@ assert \at(t L1)[\at(i L0)] == 4; */
This assertion is true but the evaluation is not that simple: according to ACSL's arrays semantics we convert t
into a logic array whose cells have the same value as the one of t
in the state L1
. Then we access the cell number 4
the value of i
at L0
that happens to contain 4
.
/*@ assert \at(p[\at(i L0)] L1) == 4; */
This assertion is true for the same reason as the first one.
/*@ assert \at(p L1)[\at(i L0)] == 4; */
This assertion is false because the evaluation is slightly different than in the second case: This time we evaluate the pointer p
in L1
the offset i
in L0
and we dereference the result in the current state where *(p+4)
is 6
.