Severity: medium
Domain: api
Status: VERIFIED — measured against a210d34 on 2026-08-10
Suggested labels: bug, api, undefined-behaviour
Summary
AGENTS.md requires every interface to declare virtual ~I() = default. Five headers
declare pure-virtual methods without any virtual destructor. Deleting a derived object through a
base pointer is undefined behaviour.
Measurement
$ for f in $(grep -rlE 'virtual[^;]*\)[[:space:]]*(const)?[[:space:]]*=[[:space:]]*0[[:space:]]*;' \
numerical --include=*.hpp | grep -v test); do \
grep -qE 'virtual ~|~[A-Za-z_]+\(\)[[:space:]]*=[[:space:]]*default' "$f" || echo "$f"; \
done
Affected files
For contrast, ControlAffineModel in
numerical/nonlinear_control/FeedbackLinearization.hpp
does it correctly:
virtual ~ControlAffineModel() = default;
Suggested fix
Add virtual ~I() = default; to each. Never = 0 — the policy is explicit about this.
If any of these types are intended to be used only by value or via static polymorphism, mark the
destructor protected and non-virtual instead, and document that.
Notes
The prior audit reported 14 such interfaces; the count dropped to 5 after the neural-network
extraction removed the rest.
Severity: medium
Domain: api
Status: VERIFIED — measured against
a210d34on 2026-08-10Suggested labels:
bug,api,undefined-behaviourSummary
AGENTS.md requires every interface to declare
virtual ~I() = default. Five headersdeclare pure-virtual methods without any virtual destructor. Deleting a derived object through a
base pointer is undefined behaviour.
Measurement
Affected files
For contrast,
ControlAffineModelinnumerical/nonlinear_control/FeedbackLinearization.hpp
does it correctly:
Suggested fix
Add
virtual ~I() = default;to each. Never= 0— the policy is explicit about this.If any of these types are intended to be used only by value or via static polymorphism, mark the
destructor
protectedand non-virtual instead, and document that.Notes
The prior audit reported 14 such interfaces; the count dropped to 5 after the neural-network
extraction removed the rest.