BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsla_nonnullarg.h
Go to the documentation of this file.
1/// @file bsla_nonnullarg.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsla_nonnullarg.h -*-C++-*-
8#ifndef INCLUDED_BSLA_NONNULLARG
9#define INCLUDED_BSLA_NONNULLARG
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsla_nonnullarg bsla_nonnullarg
15/// @brief Provide macros to hint at null arguments to functions.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsla
19/// @{
20/// @addtogroup bsla_nonnullarg
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsla_nonnullarg-purpose"> Purpose</a>
25/// * <a href="#bsla_nonnullarg-macros"> Macros </a>
26/// * <a href="#bsla_nonnullarg-description"> Description </a>
27/// * <a href="#bsla_nonnullarg-macro-reference"> Macro Reference </a>
28/// * <a href="#bsla_nonnullarg-usage"> Usage </a>
29/// * <a href="#bsla_nonnullarg-example-1-passing-null-to-arguments-annotated-as-non-null"> Example 1: Passing Null to Arguments Annotated as Non-Null </a>
30///
31/// # Purpose {#bsla_nonnullarg-purpose}
32/// Provide macros to hint at null arguments to functions.
33///
34/// # Macros {#bsla_nonnullarg-macros}
35///
36/// - BSLA_NONNULLARGS: warn if any pointer arguments are null
37/// - BSLA_NONNULLARG(...): warn if indexed arguments are null
38/// - BSLA_NONNULLARGS_IS_ACTIVE: defined if `BSLA_NONNULLARGS` is active
39/// - BSLA_NONNULLARG_IS_ACTIVE: defined if `BSLA_NONNULLARG` is active
40///
41/// @see bsla_annotations
42///
43/// # Description {#bsla_nonnullarg-description}
44/// This component provides preprocessor macros that define
45/// compiler-specific compile-time annotations. These macros instruct the
46/// compiler to warn if null is passed to certain arguments to a function, or,
47/// on platforms where the feature is not supported, expand to nothing.
48///
49/// Note that the annotations cause warnings to be emitted if the covered
50/// argument is passed:
51/// * `NULL`
52/// * 0
53/// * `static_cast<TYPE *>(0)`
54/// * `nullptr` (with C++11)
55/// * a `const` variable known to be 0 (clang only, no warning with g++)
56///
57/// ## Macro Reference {#bsla_nonnullarg-macro-reference}
58///
59///
60/// `BSLA_NONNULLARGS`:
61/// This annotation indicates that a compiler warning is to be issued if
62/// any of the pointer arguments to this function are passed null.
63///
64/// `BSLA_NONNULLARG(...)`:
65/// This annotation, passed a variable-length list of positive integers,
66/// indicates that a compiler warning is to be issued if null is passed to
67/// a pointer argument at any of the specified indices, where the first
68/// argument of the annotated function has an index of 1. Note that for
69/// non-static member functions, the implicit `this` argument has index 1.
70///
71/// `BSLA_NONNULLARG_IS_ACTIVE`:
72/// The macro `BSLA_NONNULLARGS_IS_ACTIVE` is defined if `BSLA_NONNULLARGS`
73/// expands to something with the desired effect; otherwise
74/// `BSLA_NONNULLARGS_IS_ACTIVE` is not defined and `BSLA_NONNULLARGS`
75/// expands to nothing.
76///
77/// `BSLS_NONNULLARGS_IS_ACTIVE`:
78/// The macro `BSLA_NONNULLARG_IS_ACTIVE` is defined if `BSLA_NONNULLARG`
79/// expands to something with the desired effect; otherwise
80/// `BSLA_NONNULLARG_IS_ACTIVE` is not defined and `BSLA_NONNULLARG`
81/// expands to nothing.
82///
83/// ## Usage {#bsla_nonnullarg-usage}
84///
85///
86/// This section illustrates intended use of this component.
87///
88/// ### Example 1: Passing Null to Arguments Annotated as Non-Null {#bsla_nonnullarg-example-1-passing-null-to-arguments-annotated-as-non-null}
89///
90///
91/// First, we define a function, `usagePrint1`, annotated such that a compiler
92/// warning will occur if the first argument of the annotated function is passed
93/// 0, `NULL`, `nullptr`, or (on clang) a null pointer constant expression:
94/// @code
95/// // Print the specified 'string' the specified 'repetition' times.
96/// void usagePrint1(const char *string, int repetition) BSLA_NONNULLARG(1);
97///
98/// void usagePrint1(const char *string, int repetition)
99/// {
100/// for (int ii = 0; ii < repetition; ++ii) {
101/// printf("%s\n", string);
102/// }
103/// }
104/// @endcode
105/// Then, we define a nearly identical function annotated with
106/// `BSLA_NONNULLARGS` instead. Note that only pointer arguments are affected
107/// by this annotation -- `repetition` is not affected and may be passed 0
108/// without a warning being emitted:
109/// @code
110/// // Print the specified 'string' the specified 'repetition' times.
111/// void usagePrint2(const char *string, int repetition) BSLA_NONNULLARGS;
112///
113/// void usagePrint2(const char *string, int repetition)
114/// {
115/// for (int ii = 0; ii < repetition; ++ii) {
116/// printf("%s\n", string);
117/// }
118/// }
119/// @endcode
120/// So the two different annotations on these functions have an identical
121/// effect -- affecting the `string` argument but not the `repetition` argument.
122///
123/// Next, in `main`, we call both functions with a non-null first argument, and
124/// observe that no warning occurs. Note that even though 0 is passed to the
125/// integer argument to `usagePrint2` and the `BSLA_NONNULLARGS` annotation was
126/// used, non-pointer arguments are not affected by that annotation:
127/// @code
128/// usagePrint1("woof", 0);
129/// usagePrint2("meow", 0);
130/// @endcode
131/// Then, we call both functions passing the first argument a variable whose
132/// value is known by the compiler to be null, but since `np1` is a non-`const`
133/// variable, no warning is issued:
134/// @code
135/// char *np1 = NULL;
136/// usagePrint1(np1, 0);
137/// usagePrint2(np1, 0);
138/// @endcode
139/// Now, we call both functions passing various forms of constant null pointer
140/// expressions to the first argument:
141/// @code
142/// usagePrint1( 0, -10);
143/// usagePrint2( 0, -10);
144///
145/// usagePrint1(NULL, -20);
146/// usagePrint2(NULL, -20);
147///
148/// usagePrint1(static_cast<char *>(0), -30);
149/// usagePrint2(static_cast<char *>(0), -30);
150///
151/// #if __cplusplus >= 201103L
152/// usagePrint1(nullptr, -40);
153/// usagePrint2(nullptr, -40);
154/// #endif
155///
156/// char * const np2 = 0; // 'np2', unlike 'np1' above, is 'const'.
157/// usagePrint1(np2, -50); // Warning with clang, not g++
158/// usagePrint2(np2, -50); // Warning with clang, not g++
159/// @endcode
160/// Finally, we observe that the above calls result in the following warnings
161/// with clang w/C++11 support:
162/// @code
163/// .../bsla_nonnullarg.t.cpp:376:30: warning: null passed to a callee that
164/// requires a non-null argument [-Wnonnull]
165/// usagePrint1( 0, -10);
166/// ~ ^
167/// .../bsla_nonnullarg.t.cpp:377:30: warning: null passed to a callee that
168/// requires a non-null argument [-Wnonnull]
169/// usagePrint2( 0, -10);
170/// ~ ^
171/// .../bsla_nonnullarg.t.cpp:379:30: warning: null passed to a callee that
172/// requires a non-null argument [-Wnonnull]
173/// usagePrint1(NULL, -20);
174/// ~~~~ ^
175/// .../bsla_nonnullarg.t.cpp:380:30: warning: null passed to a callee that
176/// requires a non-null argument [-Wnonnull]
177/// usagePrint2(NULL, -20);
178/// ~~~~ ^
179/// .../bsla_nonnullarg.t.cpp:382:48: warning: null passed to a callee that
180/// requires a non-null argument [-Wnonnull]
181/// usagePrint1(static_cast<char *>(0), -30);
182/// ~~~~~~~~~~~~~~~~~~~~~~ ^
183/// .../bsla_nonnullarg.t.cpp:383:48: warning: null passed to a callee that
184/// requires a non-null argument [-Wnonnull]
185/// usagePrint2(static_cast<char *>(0), -30);
186/// ~~~~~~~~~~~~~~~~~~~~~~ ^
187/// .../bsla_nonnullarg.t.cpp:386:37: warning: null passed to a callee that
188/// requires a non-null argument [-Wnonnull]
189/// usagePrint1(nullptr, -40);
190/// ~~~~~~~ ^
191/// .../bsla_nonnullarg.t.cpp:387:37: warning: null passed to a callee that
192/// requires a non-null argument [-Wnonnull]
193/// usagePrint2(nullptr, -40);
194/// ~~~~~~~ ^
195/// .../bsla_nonnullarg.t.cpp:391:29: warning: null passed to a callee that
196/// requires a non-null argument [-Wnonnull]
197/// usagePrint1(np2, -50); // Warning with clang, not g++
198/// ~~~ ^
199/// .../bsla_nonnullarg.t.cpp:392:29: warning: null passed to a callee that
200/// requires a non-null argument [-Wnonnull]
201/// usagePrint2(np2, -50); // Warning with clang, not g++
202/// ~~~ ^
203/// @endcode
204/// @}
205/** @} */
206/** @} */
207
208/** @addtogroup bsl
209 * @{
210 */
211/** @addtogroup bsla
212 * @{
213 */
214/** @addtogroup bsla_nonnullarg
215 * @{
216 */
217
218#include <bsls_platform.h>
219
220 // =============================
221 // Checks for Pre-Defined macros
222 // =============================
223
224#if defined(BSLA_NONNULLARG)
225#error BSLA_NONNULLARG is already defined!
226#endif
227
228#if defined(BSLA_NONNULLARG_IS_ACTIVE)
229#error BSLA_NONNULLARG_IS_ACTIVE is already defined!
230#endif
231
232#if defined(BSLA_NONNULLARGS)
233#error BSLA_NONNULLARGS is already defined!
234#endif
235
236#if defined(BSLA_NONNULLARGS_IS_ACTIVE)
237#error BSLA_NONNULLARGS_IS_ACTIVE is already defined!
238#endif
239 // =========================
240 // Set macros as appropriate
241 // =========================
242
243#if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
244 #define BSLA_NONNULLARG(...) __attribute__((__nonnull__(__VA_ARGS__)))
245 #define BSLA_NONNULLARGS __attribute__((__nonnull__))
246
247 #define BSLA_NONNULLARG_IS_ACTIVE 1
248 #define BSLA_NONNULLARGS_IS_ACTIVE 1
249#else
250 #define BSLA_NONNULLARG(...)
251 #define BSLA_NONNULLARGS
252#endif
253
254#endif
255
256// ----------------------------------------------------------------------------
257// Copyright 2019 Bloomberg Finance L.P.
258//
259// Licensed under the Apache License, Version 2.0 (the "License");
260// you may not use this file except in compliance with the License.
261// You may obtain a copy of the License at
262//
263// http://www.apache.org/licenses/LICENSE-2.0
264//
265// Unless required by applicable law or agreed to in writing, software
266// distributed under the License is distributed on an "AS IS" BASIS,
267// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
268// See the License for the specific language governing permissions and
269// limitations under the License.
270// ----------------------------- END-OF-FILE ----------------------------------
271
272/** @} */
273/** @} */
274/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195