Back to home page

EIC code displayed by LXR

 
 

    


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_