← Blog

A checker that says "I don't know"

26 August 2026 · Mansour Ayouni

Ring++ includes a tool that reads your code without running it and tells you about mistakes — calling a function with the wrong number of arguments, say. It found two functions in Ring's own standard library that had never worked in any release — both since fixed upstream, because of that report.

Sometimes it reads a program and reports neither "clean" nor a list of problems. It reports NO VERDICT: I could not see all of this, so I am not going to tell you it is fine.

People occasionally ask why it does not just say "probably fine" and move on. This is the answer.

The one thing such a tool is for

A checker has exactly one asset, and it is not the number of problems it finds. It is this:

It is never wrong when it says your code is fine.

Lose that, and the tool becomes worse than nothing. Not neutral — worse. A checker nobody runs wastes a download. A checker that says "clean" when it has not looked properly makes you stop looking too, and it does that at the exact moment when something was there to find.

When it cannot see everything

Ring programs are assembled from files that pull in other files. To know that a function is called correctly, the checker has to find where that function was defined — possibly several files away.

Usually it can follow the whole chain. Sometimes it cannot: a file lives somewhere it was not told about, or one file fails to parse, or a name genuinely has two definitions and there is no way to tell which one wins.

At that moment the tool has two options, and only one of them is honest.

Report clean

Comfortable, and usually right. But the one time it is wrong, it is wrong in the direction that costs the most — and the user has no way of telling that case apart from a real all-clear.

Refuse a verdict

Says exactly what happened: this part could not be followed, so nothing is being claimed about it. Less satisfying. Always true.

Ring++ takes the second one, and tells you which file it could not follow so you can point it at the missing piece and ask again.

Why this project takes it personally

Because it has been caught by exactly this failure twice — in its own measurement tools, not in someone else's code.

Both times the pattern was identical: a program reported success while silently doing nothing. One check had been written to look for a tool that was not installed on the machine; finding nothing, it matched nothing, allowed everything, and printed a clean result every time it ran. It was not guarding anything at all.

A guard that reports success by staying quiet is indistinguishable from one that works. That sentence is now a rule here: every safety check has to be watched failing on purpose before it is trusted to pass.

A checker that guesses "clean" is the same defect wearing better clothes. Having been fooled twice by our own tools, we were not going to build a third one that could fool a user.

What it costs

Honesty of this kind is not free, and the bill is small but real: you will occasionally get NO VERDICT when the code was in fact fine, and you will have to tell the tool where the missing files are before it will commit to an answer.

The trade is deliberate. Across Ring's own 1,959 files the checker reported zero false alarms — no invented problems in correct code — while finding three real ones. That number is only worth something because the tool refuses to pad it with guesses.

The static analysis page has the bug it found in Ring's shipped standard library, and the three false alarms an earlier version did produce, with what each one cost.

Next

Static analysis We spent a day attacking our own library