Chapter 11 — Your first verified function¶
We connect Part I’s Hoare triple to CppVerify syntax.
The program¶
int abs(int x)
pre(x >= -2147483647)
post(result >= 0)
{
return x < 0 ? -x : x;
}
pre(x >= -2147483647)— the precondition the caller must satisfy. It admits everyintexceptINT_MIN: CppVerify uses honest machine integers, and-INT_MINoverflows (see Chapter 16 — When verification fails). Withpre(true)the verifier correctly rejects this function and reportsx = INT_MINas a counterexample — a real bug it just caught for you.post(result >= 0)—resultis the return value (Part I: postcondition).The verifier must prove: assuming the precondition and the implementation,
result >= 0follows.
Run verification¶
./build/bin/cpp-verify abs.cpp
What the verifier did (conceptually)¶
Built a VC: the precondition and path facts about
ximplyresult >= 0.Asked Z3: is
(facts ∧ ¬(result >= 0))unsatisfiable?Unsat ⇒ verified.
If you return x unchanged, Z3 finds a model with a negative x — counterexample.
Compile the same file¶
clang++ -std=c++17 -fverify-contracts -c abs.cpp -o abs.o
Verification runs in parallel; ghost code is stripped — no runtime contract overhead.
Larger programs compose modularly: callee contracts are assumed at call sites, including nested
calls such as return f(g(x)) (see Chapter 17 — Backends, modular calls, and debugging).