1// Copyright 2023 The Abseil Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// -----------------------------------------------------------------------------
16// File: nullability.h
17// -----------------------------------------------------------------------------
18//
19// This header file defines a set of "templated annotations" for designating the
20// expected nullability of pointers. These annotations allow you to designate
21// pointers in one of three classification states:
22//
23// * "Non-null" (for pointers annotated `Nonnull<T>`), indicating that it is
24// invalid for the given pointer to ever be null.
25// * "Nullable" (for pointers annotated `Nullable<T>`), indicating that it is
26// valid for the given pointer to be null.
27// * "Unknown" (for pointers annotated `NullabilityUnknown<T>`), indicating
28// that the given pointer has not been yet classified as either nullable or
29// non-null. This is the default state of unannotated pointers.
30//
31// NOTE: unannotated pointers implicitly bear the annotation
32// `NullabilityUnknown<T>`; you should rarely, if ever, see this annotation used
33// in the codebase explicitly.
34//
35// -----------------------------------------------------------------------------
36// Nullability and Contracts
37// -----------------------------------------------------------------------------
38//
39// These nullability annotations allow you to more clearly specify contracts on
40// software components by narrowing the *preconditions*, *postconditions*, and
41// *invariants* of pointer state(s) in any given interface. It then depends on
42// context who is responsible for fulfilling the annotation's requirements.
43//
44// For example, a function may receive a pointer argument. Designating that
45// pointer argument as "non-null" tightens the precondition of the contract of
46// that function. It is then the responsibility of anyone calling such a
47// function to ensure that the passed pointer is not null.
48//
49// Similarly, a function may have a pointer as a return value. Designating that
50// return value as "non-null" tightens the postcondition of the contract of that
51// function. In this case, however, it is the responsibility of the function
52// itself to ensure that the returned pointer is not null.
53//
54// Clearly defining these contracts allows providers (and consumers) of such
55// pointers to have more confidence in their null state. If a function declares
56// a return value as "non-null", for example, the caller should not need to
57// check whether the returned value is `nullptr`; it can simply assume the
58// pointer is valid.
59//
60// Of course most interfaces already have expectations on the nullability state
61// of pointers, and these expectations are, in effect, a contract; often,
62// however, those contracts are either poorly or partially specified, assumed,
63// or misunderstood. These nullability annotations are designed to allow you to
64// formalize those contracts within the codebase.
65//
66// -----------------------------------------------------------------------------
67// Using Nullability Annotations
68// -----------------------------------------------------------------------------
69//
70// It is important to note that these annotations are not distinct strong
71// *types*. They are alias templates defined to be equal to the underlying
72// pointer type. A pointer annotated `Nonnull<T*>`, for example, is simply a
73// pointer of type `T*`. Each annotation acts as a form of documentation about
74// the contract for the given pointer. Each annotation requires providers or
75// consumers of these pointers across API boundaries to take appropriate steps
76// when setting or using these pointers:
77//
78// * "Non-null" pointers should never be null. It is the responsibility of the
79// provider of this pointer to ensure that the pointer may never be set to
80// null. Consumers of such pointers can treat such pointers as non-null.
81// * "Nullable" pointers may or may not be null. Consumers of such pointers
82// should precede any usage of that pointer (e.g. a dereference operation)
83// with a a `nullptr` check.
84// * "Unknown" pointers may be either "non-null" or "nullable" but have not been
85// definitively determined to be in either classification state. Providers of
86// such pointers across API boundaries should determine -- over time -- to
87// annotate the pointer in either of the above two states. Consumers of such
88// pointers across an API boundary should continue to treat such pointers as
89// they currently do.
90//
91// Example:
92//
93// // PaySalary() requires the passed pointer to an `Employee` to be non-null.
94// void PaySalary(absl::Nonnull<Employee *> e) {
95// pay(e->salary); // OK to dereference
96// }
97//
98// // CompleteTransaction() guarantees the returned pointer to an `Account` to
99// // be non-null.
100// absl::Nonnull<Account *> balance CompleteTransaction(double fee) {
101// ...
102// }
103//
104// // Note that specifying a nullability annotation does not prevent someone
105// // from violating the contract:
106//
107// Nullable<Employee *> find(Map& employees, std::string_view name);
108//
109// void g(Map& employees) {
110// Employee *e = find(employees, "Pat");
111// // `e` can now be null.
112// PaySalary(e); // Violates contract, but compiles!
113// }
114//
115// Nullability annotations, in other words, are useful for defining and
116// narrowing contracts; *enforcement* of those contracts depends on use and any
117// additional (static or dynamic analysis) tooling.
118//
119// NOTE: The "unknown" annotation state indicates that a pointer's contract has
120// not yet been positively identified. The unknown state therefore acts as a
121// form of documentation of your technical debt, and a codebase that adopts
122// nullability annotations should aspire to annotate every pointer as either
123// "non-null" or "nullable".
124//
125// -----------------------------------------------------------------------------
126// Applicability of Nullability Annotations
127// -----------------------------------------------------------------------------
128//
129// By default, nullability annotations are applicable to raw and smart
130// pointers. User-defined types can indicate compatibility with nullability
131// annotations by providing an `absl_nullability_compatible` nested type. The
132// actual definition of this inner type is not relevant as it is used merely as
133// a marker. It is common to use a using declaration of
134// `absl_nullability_compatible` set to void.
135//
136// // Example:
137// struct MyPtr {
138// using absl_nullability_compatible = void;
139// ...
140// };
141//
142// DISCLAIMER:
143// ===========================================================================
144// These nullability annotations are primarily a human readable signal about the
145// intended contract of the pointer. They are not *types* and do not currently
146// provide any correctness guarantees. For example, a pointer annotated as
147// `Nonnull<T*>` is *not guaranteed* to be non-null, and the compiler won't
148// alert or prevent assignment of a `Nullable<T*>` to a `Nonnull<T*>`.
149// ===========================================================================
150#ifndef ABSL_BASE_NULLABILITY_H_
151#define ABSL_BASE_NULLABILITY_H_
152
153#include "absl/base/internal/nullability_impl.h"
154
155namespace absl {
156
157// absl::Nonnull
158//
159// The indicated pointer is never null. It is the responsibility of the provider
160// of this pointer across an API boundary to ensure that the pointer is never be
161// set to null. Consumers of this pointer across an API boundary may safely
162// dereference the pointer.
163//
164// Example:
165//
166// // `employee` is designated as not null.
167// void PaySalary(absl::Nonnull<Employee *> employee) {
168// pay(*employee); // OK to dereference
169// }
170template <typename T>
171using Nonnull = nullability_internal::NonnullImpl<T>;
172
173// absl::Nullable
174//
175// The indicated pointer may, by design, be either null or non-null. Consumers
176// of this pointer across an API boundary should perform a `nullptr` check
177// before performing any operation using the pointer.
178//
179// Example:
180//
181// // `employee` may be null.
182// void PaySalary(absl::Nullable<Employee *> employee) {
183// if (employee != nullptr) {
184// Pay(*employee); // OK to dereference
185// }
186// }
187template <typename T>
188using Nullable = nullability_internal::NullableImpl<T>;
189
190// absl::NullabilityUnknown (default)
191//
192// The indicated pointer has not yet been determined to be definitively
193// "non-null" or "nullable." Providers of such pointers across API boundaries
194// should, over time, annotate such pointers as either "non-null" or "nullable."
195// Consumers of these pointers across an API boundary should treat such pointers
196// with the same caution they treat currently unannotated pointers. Most
197// existing code will have "unknown" pointers, which should eventually be
198// migrated into one of the above two nullability states: `Nonnull<T>` or
199// `Nullable<T>`.
200//
201// NOTE: Because this annotation is the global default state, pointers without
202// any annotation are assumed to have "unknown" semantics. This assumption is
203// designed to minimize churn and reduce clutter within the codebase.
204//
205// Example:
206//
207// // `employee`s nullability state is unknown.
208// void PaySalary(absl::NullabilityUnknown<Employee *> employee) {
209// Pay(*employee); // Potentially dangerous. API provider should investigate.
210// }
211//
212// Note that a pointer without an annotation, by default, is assumed to have the
213// annotation `NullabilityUnknown`.
214//
215// // `employee`s nullability state is unknown.
216// void PaySalary(Employee* employee) {
217// Pay(*employee); // Potentially dangerous. API provider should investigate.
218// }
219template <typename T>
220using NullabilityUnknown = nullability_internal::NullabilityUnknownImpl<T>;
221
222} // namespace absl
223
224#endif // ABSL_BASE_NULLABILITY_H_
225