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 adding the ABSL_NULLABILITY_COMPATIBLE attribute. 132 // 133 // // Example: 134 // struct ABSL_NULLABILITY_COMPATIBLE MyPtr { 135 // ... 136 // }; 137 // 138 // Note: Compilers that don't support the `nullability_on_classes` feature will 139 // allow nullability annotations to be applied to any type, not just ones 140 // marked with `ABSL_NULLABILITY_COMPATIBLE`. 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/config.h" 154 #include "absl/base/internal/nullability_impl.h" 155 156 // ABSL_POINTERS_DEFAULT_NONNULL 157 // 158 // This macro specifies that all unannotated pointer types within the given 159 // file are designated as nonnull (instead of the default "unknown"). This macro 160 // exists as a standalone statement and applies default nonnull behavior to all 161 // subsequent pointers; as a result, place this macro as the first non-comment, 162 // non-`#include` line in a file. 163 // 164 // Example: 165 // 166 // #include "absl/base/nullability.h" 167 // 168 // ABSL_POINTERS_DEFAULT_NONNULL 169 // 170 // void FillMessage(Message *m); // implicitly non-null 171 // absl::Nullable<T*> GetNullablePtr(); // explicitly nullable 172 // absl::NullabilityUnknown<T*> GetUnknownPtr(); // explicitly unknown 173 // 174 // The macro can be safely used in header files -- it will not affect any files 175 // that include it. 176 // 177 // In files with the macro, plain `T*` syntax means `absl::Nonnull<T*>`, and the 178 // exceptions (`Nullable` and `NullabilityUnknown`) must be marked 179 // explicitly. The same holds, correspondingly, for smart pointer types. 180 // 181 // For comparison, without the macro, all unannotated pointers would default to 182 // unknown, and otherwise require explicit annotations to change this behavior: 183 // 184 // #include "absl/base/nullability.h" 185 // 186 // void FillMessage(absl::Nonnull<Message*> m); // explicitly non-null 187 // absl::Nullable<T*> GetNullablePtr(); // explicitly nullable 188 // T* GetUnknownPtr(); // implicitly unknown 189 // 190 // No-op except for being a human readable signal. 191 #define ABSL_POINTERS_DEFAULT_NONNULL 192 193 namespace absl { 194 ABSL_NAMESPACE_BEGIN 195 196 // absl::Nonnull (default with `ABSL_POINTERS_DEFAULT_NONNULL`) 197 // 198 // The indicated pointer is never null. It is the responsibility of the provider 199 // of this pointer across an API boundary to ensure that the pointer is never 200 // set to null. Consumers of this pointer across an API boundary may safely 201 // dereference the pointer. 202 // 203 // Example: 204 // 205 // // `employee` is designated as not null. 206 // void PaySalary(absl::Nonnull<Employee *> employee) { 207 // pay(*employee); // OK to dereference 208 // } 209 template <typename T> 210 using Nonnull = nullability_internal::NonnullImpl<T>; 211 212 // absl::Nullable 213 // 214 // The indicated pointer may, by design, be either null or non-null. Consumers 215 // of this pointer across an API boundary should perform a `nullptr` check 216 // before performing any operation using the pointer. 217 // 218 // Example: 219 // 220 // // `employee` may be null. 221 // void PaySalary(absl::Nullable<Employee *> employee) { 222 // if (employee != nullptr) { 223 // Pay(*employee); // OK to dereference 224 // } 225 // } 226 template <typename T> 227 using Nullable = nullability_internal::NullableImpl<T>; 228 229 // absl::NullabilityUnknown (default without `ABSL_POINTERS_DEFAULT_NONNULL`) 230 // 231 // The indicated pointer has not yet been determined to be definitively 232 // "non-null" or "nullable." Providers of such pointers across API boundaries 233 // should, over time, annotate such pointers as either "non-null" or "nullable." 234 // Consumers of these pointers across an API boundary should treat such pointers 235 // with the same caution they treat currently unannotated pointers. Most 236 // existing code will have "unknown" pointers, which should eventually be 237 // migrated into one of the above two nullability states: `Nonnull<T>` or 238 // `Nullable<T>`. 239 // 240 // NOTE: For files that do not specify `ABSL_POINTERS_DEFAULT_NONNULL`, 241 // because this annotation is the global default state, unannotated pointers are 242 // are assumed to have "unknown" semantics. This assumption is designed to 243 // minimize churn and reduce clutter within the codebase. 244 // 245 // Example: 246 // 247 // // `employee`s nullability state is unknown. 248 // void PaySalary(absl::NullabilityUnknown<Employee *> employee) { 249 // Pay(*employee); // Potentially dangerous. API provider should investigate. 250 // } 251 // 252 // Note that a pointer without an annotation, by default, is assumed to have the 253 // annotation `NullabilityUnknown`. 254 // 255 // // `employee`s nullability state is unknown. 256 // void PaySalary(Employee* employee) { 257 // Pay(*employee); // Potentially dangerous. API provider should investigate. 258 // } 259 template <typename T> 260 using NullabilityUnknown = nullability_internal::NullabilityUnknownImpl<T>; 261 262 ABSL_NAMESPACE_END 263 } // namespace absl 264 265 // ABSL_NULLABILITY_COMPATIBLE 266 // 267 // Indicates that a class is compatible with nullability annotations. 268 // 269 // For example: 270 // 271 // struct ABSL_NULLABILITY_COMPATIBLE MyPtr { 272 // ... 273 // }; 274 // 275 // Note: Compilers that don't support the `nullability_on_classes` feature will 276 // allow nullability annotations to be applied to any type, not just ones marked 277 // with `ABSL_NULLABILITY_COMPATIBLE`. 278 #if ABSL_HAVE_FEATURE(nullability_on_classes) 279 #define ABSL_NULLABILITY_COMPATIBLE _Nullable 280 #else 281 #define ABSL_NULLABILITY_COMPATIBLE 282 #endif 283 284 #endif // ABSL_BASE_NULLABILITY_H_ 285