|
|
|||
File indexing completed on 2025-12-16 09:40:43
0001 // Copyright 2023 The Abseil Authors. 0002 // 0003 // Licensed under the Apache License, Version 2.0 (the "License"); 0004 // you may not use this file except in compliance with the License. 0005 // You may obtain a copy of the License at 0006 // 0007 // https://www.apache.org/licenses/LICENSE-2.0 0008 // 0009 // Unless required by applicable law or agreed to in writing, software 0010 // distributed under the License is distributed on an "AS IS" BASIS, 0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0012 // See the License for the specific language governing permissions and 0013 // limitations under the License. 0014 // 0015 // ----------------------------------------------------------------------------- 0016 // File: nullability.h 0017 // ----------------------------------------------------------------------------- 0018 // 0019 // This header file defines a set of "templated annotations" for designating the 0020 // expected nullability of pointers. These annotations allow you to designate 0021 // pointers in one of three classification states: 0022 // 0023 // * "Non-null" (for pointers annotated `Nonnull<T>`), indicating that it is 0024 // invalid for the given pointer to ever be null. 0025 // * "Nullable" (for pointers annotated `Nullable<T>`), indicating that it is 0026 // valid for the given pointer to be null. 0027 // * "Unknown" (for pointers annotated `NullabilityUnknown<T>`), indicating 0028 // that the given pointer has not been yet classified as either nullable or 0029 // non-null. This is the default state of unannotated pointers. 0030 // 0031 // NOTE: unannotated pointers implicitly bear the annotation 0032 // `NullabilityUnknown<T>`; you should rarely, if ever, see this annotation used 0033 // in the codebase explicitly. 0034 // 0035 // ----------------------------------------------------------------------------- 0036 // Nullability and Contracts 0037 // ----------------------------------------------------------------------------- 0038 // 0039 // These nullability annotations allow you to more clearly specify contracts on 0040 // software components by narrowing the *preconditions*, *postconditions*, and 0041 // *invariants* of pointer state(s) in any given interface. It then depends on 0042 // context who is responsible for fulfilling the annotation's requirements. 0043 // 0044 // For example, a function may receive a pointer argument. Designating that 0045 // pointer argument as "non-null" tightens the precondition of the contract of 0046 // that function. It is then the responsibility of anyone calling such a 0047 // function to ensure that the passed pointer is not null. 0048 // 0049 // Similarly, a function may have a pointer as a return value. Designating that 0050 // return value as "non-null" tightens the postcondition of the contract of that 0051 // function. In this case, however, it is the responsibility of the function 0052 // itself to ensure that the returned pointer is not null. 0053 // 0054 // Clearly defining these contracts allows providers (and consumers) of such 0055 // pointers to have more confidence in their null state. If a function declares 0056 // a return value as "non-null", for example, the caller should not need to 0057 // check whether the returned value is `nullptr`; it can simply assume the 0058 // pointer is valid. 0059 // 0060 // Of course most interfaces already have expectations on the nullability state 0061 // of pointers, and these expectations are, in effect, a contract; often, 0062 // however, those contracts are either poorly or partially specified, assumed, 0063 // or misunderstood. These nullability annotations are designed to allow you to 0064 // formalize those contracts within the codebase. 0065 // 0066 // ----------------------------------------------------------------------------- 0067 // Using Nullability Annotations 0068 // ----------------------------------------------------------------------------- 0069 // 0070 // It is important to note that these annotations are not distinct strong 0071 // *types*. They are alias templates defined to be equal to the underlying 0072 // pointer type. A pointer annotated `Nonnull<T*>`, for example, is simply a 0073 // pointer of type `T*`. Each annotation acts as a form of documentation about 0074 // the contract for the given pointer. Each annotation requires providers or 0075 // consumers of these pointers across API boundaries to take appropriate steps 0076 // when setting or using these pointers: 0077 // 0078 // * "Non-null" pointers should never be null. It is the responsibility of the 0079 // provider of this pointer to ensure that the pointer may never be set to 0080 // null. Consumers of such pointers can treat such pointers as non-null. 0081 // * "Nullable" pointers may or may not be null. Consumers of such pointers 0082 // should precede any usage of that pointer (e.g. a dereference operation) 0083 // with a a `nullptr` check. 0084 // * "Unknown" pointers may be either "non-null" or "nullable" but have not been 0085 // definitively determined to be in either classification state. Providers of 0086 // such pointers across API boundaries should determine -- over time -- to 0087 // annotate the pointer in either of the above two states. Consumers of such 0088 // pointers across an API boundary should continue to treat such pointers as 0089 // they currently do. 0090 // 0091 // Example: 0092 // 0093 // // PaySalary() requires the passed pointer to an `Employee` to be non-null. 0094 // void PaySalary(absl::Nonnull<Employee *> e) { 0095 // pay(e->salary); // OK to dereference 0096 // } 0097 // 0098 // // CompleteTransaction() guarantees the returned pointer to an `Account` to 0099 // // be non-null. 0100 // absl::Nonnull<Account *> balance CompleteTransaction(double fee) { 0101 // ... 0102 // } 0103 // 0104 // // Note that specifying a nullability annotation does not prevent someone 0105 // // from violating the contract: 0106 // 0107 // Nullable<Employee *> find(Map& employees, std::string_view name); 0108 // 0109 // void g(Map& employees) { 0110 // Employee *e = find(employees, "Pat"); 0111 // // `e` can now be null. 0112 // PaySalary(e); // Violates contract, but compiles! 0113 // } 0114 // 0115 // Nullability annotations, in other words, are useful for defining and 0116 // narrowing contracts; *enforcement* of those contracts depends on use and any 0117 // additional (static or dynamic analysis) tooling. 0118 // 0119 // NOTE: The "unknown" annotation state indicates that a pointer's contract has 0120 // not yet been positively identified. The unknown state therefore acts as a 0121 // form of documentation of your technical debt, and a codebase that adopts 0122 // nullability annotations should aspire to annotate every pointer as either 0123 // "non-null" or "nullable". 0124 // 0125 // ----------------------------------------------------------------------------- 0126 // Applicability of Nullability Annotations 0127 // ----------------------------------------------------------------------------- 0128 // 0129 // By default, nullability annotations are applicable to raw and smart 0130 // pointers. User-defined types can indicate compatibility with nullability 0131 // annotations by adding the ABSL_NULLABILITY_COMPATIBLE attribute. 0132 // 0133 // // Example: 0134 // struct ABSL_NULLABILITY_COMPATIBLE MyPtr { 0135 // ... 0136 // }; 0137 // 0138 // Note: For the time being, nullability-compatible classes should additionally 0139 // be marked with an `absl_nullability_compatible` nested type (this will soon 0140 // be deprecated). The actual definition of this inner type is not relevant as 0141 // it is used merely as a marker. It is common to use a using declaration of 0142 // `absl_nullability_compatible` set to void. 0143 // 0144 // // Example: 0145 // struct MyPtr { 0146 // using absl_nullability_compatible = void; 0147 // ... 0148 // }; 0149 // 0150 // DISCLAIMER: 0151 // =========================================================================== 0152 // These nullability annotations are primarily a human readable signal about the 0153 // intended contract of the pointer. They are not *types* and do not currently 0154 // provide any correctness guarantees. For example, a pointer annotated as 0155 // `Nonnull<T*>` is *not guaranteed* to be non-null, and the compiler won't 0156 // alert or prevent assignment of a `Nullable<T*>` to a `Nonnull<T*>`. 0157 // =========================================================================== 0158 #ifndef ABSL_BASE_NULLABILITY_H_ 0159 #define ABSL_BASE_NULLABILITY_H_ 0160 0161 #include "absl/base/config.h" 0162 #include "absl/base/internal/nullability_impl.h" 0163 0164 namespace absl { 0165 ABSL_NAMESPACE_BEGIN 0166 0167 // absl::Nonnull 0168 // 0169 // The indicated pointer is never null. It is the responsibility of the provider 0170 // of this pointer across an API boundary to ensure that the pointer is never 0171 // set to null. Consumers of this pointer across an API boundary may safely 0172 // dereference the pointer. 0173 // 0174 // Example: 0175 // 0176 // // `employee` is designated as not null. 0177 // void PaySalary(absl::Nonnull<Employee *> employee) { 0178 // pay(*employee); // OK to dereference 0179 // } 0180 template <typename T> 0181 using Nonnull = nullability_internal::NonnullImpl<T>; 0182 0183 // absl::Nullable 0184 // 0185 // The indicated pointer may, by design, be either null or non-null. Consumers 0186 // of this pointer across an API boundary should perform a `nullptr` check 0187 // before performing any operation using the pointer. 0188 // 0189 // Example: 0190 // 0191 // // `employee` may be null. 0192 // void PaySalary(absl::Nullable<Employee *> employee) { 0193 // if (employee != nullptr) { 0194 // Pay(*employee); // OK to dereference 0195 // } 0196 // } 0197 template <typename T> 0198 using Nullable = nullability_internal::NullableImpl<T>; 0199 0200 // absl::NullabilityUnknown (default) 0201 // 0202 // The indicated pointer has not yet been determined to be definitively 0203 // "non-null" or "nullable." Providers of such pointers across API boundaries 0204 // should, over time, annotate such pointers as either "non-null" or "nullable." 0205 // Consumers of these pointers across an API boundary should treat such pointers 0206 // with the same caution they treat currently unannotated pointers. Most 0207 // existing code will have "unknown" pointers, which should eventually be 0208 // migrated into one of the above two nullability states: `Nonnull<T>` or 0209 // `Nullable<T>`. 0210 // 0211 // NOTE: Because this annotation is the global default state, unannotated 0212 // pointers are assumed to have "unknown" semantics. This assumption is designed 0213 // to minimize churn and reduce clutter within the codebase. 0214 // 0215 // Example: 0216 // 0217 // // `employee`s nullability state is unknown. 0218 // void PaySalary(absl::NullabilityUnknown<Employee *> employee) { 0219 // Pay(*employee); // Potentially dangerous. API provider should investigate. 0220 // } 0221 // 0222 // Note that a pointer without an annotation, by default, is assumed to have the 0223 // annotation `NullabilityUnknown`. 0224 // 0225 // // `employee`s nullability state is unknown. 0226 // void PaySalary(Employee* employee) { 0227 // Pay(*employee); // Potentially dangerous. API provider should investigate. 0228 // } 0229 template <typename T> 0230 using NullabilityUnknown = nullability_internal::NullabilityUnknownImpl<T>; 0231 0232 ABSL_NAMESPACE_END 0233 } // namespace absl 0234 0235 // ABSL_NULLABILITY_COMPATIBLE 0236 // 0237 // Indicates that a class is compatible with nullability annotations. 0238 // 0239 // For example: 0240 // 0241 // struct ABSL_NULLABILITY_COMPATIBLE MyPtr { 0242 // ... 0243 // }; 0244 #if ABSL_HAVE_FEATURE(nullability_on_classes) 0245 #define ABSL_NULLABILITY_COMPATIBLE _Nullable 0246 #else 0247 #define ABSL_NULLABILITY_COMPATIBLE 0248 #endif 0249 0250 #endif // ABSL_BASE_NULLABILITY_H_
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|