API C++ active any

C++ public interfaces express dispatch, ownership, and range contracts explicitly

api-cpp-001

Intent

C++ interfaces become fragile when callers must infer conversions, overriding, ownership, nullability, or range length from conventions instead of declarations.

Applicability

Applies when the diff changes public C++ constructors, virtual methods, function signatures, pointer or span boundaries, or class copy or move behavior.

What to inspect

Converting constructors and operators, override markers, pointer and size pairs, ownership transfer through raw pointers, nullability annotations, copy and move declarations, default arguments on virtual methods, and universal-reference overload sets.

Pass criteria

Public interfaces make conversions and overrides explicit, express ranges and ownership with types rather than raw pointer conventions where possible, make nullability and copy or move semantics obvious, and avoid declaration patterns whose runtime meaning differs from the call site.

Fail criteria

A public API adds an implicit conversion, omits override on an intended override, uses raw pointer plus size where a span or view is the real contract, transfers ownership ambiguously with raw pointers, depends on null or copy semantics callers cannot tell from the declaration, or mixes default arguments with virtual dispatch.

Do not flag

C ABIs, single-object non-owning pointers with obvious lifetime, generated bindings, or value-like wrapper types whose implicit conversion is already the deliberate contract.

Confidence guidance

HIGH when the declaration itself hides the contract. MEDIUM when ownership or lifetime is inferred from nearby code. LOW when part of the interface lives in generated or macro-expanded code.

Remediation

Use explicit declarations and richer boundary types so ownership, range, dispatch, and conversion behavior are visible in the interface itself.

Pass example

class Widget {
public:
  explicit Widget(std::string_view name);
  void set_items(std::span<const Item> items);
  virtual void refresh() override;
};

Fail example

class Widget {
public:
  Widget(const char* name);
  virtual void refresh(int mode = 1);
  void set_items(Item* items, int count);
};

Sources

  • A Tour of C++ — Bjarne Stroustrup, 2018 book
  • C++ Core Guidelines standard
  • Google C++ Style Guide standard
  • Effective Modern C++ — Scott Meyers, 2014 book