_Optional: a type qualifier to indicate pointer nullability
(two minute version)
tl;dr
Pointer-to-const
may have undefined behaviour on write access;
pointer-to-_Optional
may have undefined behaviour on read or write access.
Abstract
WG14 paper N3089 proposes a new type qualifier for the purpose of adding pointer nullability information to C programs.
Its goal is to provide value not only for static analysis and documentation, but also for compilers which report errors based only on existing type-compatibility rules.
The syntax and semantics are designed to be as familiar (to C programmers) and ergonomic as possible. In contrast, existing solutions are incompatible, confusing, error-prone, and intrusive.
Proposed language extension
- A new type qualifier,
_Optional
, indicates that a pointer to a so-qualified type may be null. This does not preclude any other pointer type from being null. - Types other than those of a pointed-to object or pointed-to incomplete type shall not be
_Optional
-qualified in a declaration. - The semantics of the unary
&
operator are modified so that if its operand has type “type” then its result has type “pointer to type”, with the omission of any_Optional
qualifier of the pointed-to type. - If an operand is a pointer to an
_Optional
-qualified type and its value cannot be statically proven never to be null, then implementations may generate a warning of any undefined behaviour that would occur if the value were null. - A specification of a function type that includes type qualifiers no longer has undefined behaviour. Qualifiers that are not applicable are ignored (as in C++).
The _Optional
qualifier is treated like existing qualifiers when determining compatibility between types, and when determining whether a pointer may be implicitly converted to a pointer to a differently qualified type.
Example usage
void foo(int *);
void bar(_Optional int *i)
{
*i = 10; // path-sensitive warning of unguarded dereference
if (i) {
*i = 5; // okay
}
int *j = i; // warning: initializing discard qualifiers
j = i; // warning: assignment discards qualifiers
foo(i); // warning: passing parameter discards qualifiers
foo(&*i); // path-sensitive warning of unguarded dereference
foo(&i[10]); // path-sensitive warning of unguarded dereference
if (i) {
foo(&*i); // okay
foo(&i[10]); // okay
}
}
Further reading
- Original blog post: Why C needs a new type qualifier (philosophy, inspiration, rationale, prototyping).
- The paper submitted to the WG14 committee.
- Working prototype of the functionality in the Clang compiler.