BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsls_assert.h
Go to the documentation of this file.
1/// @file bsls_assert.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_assert.h -*-C++-*-
8#ifndef INCLUDED_BSLS_ASSERT
9#define INCLUDED_BSLS_ASSERT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_assert bsls_assert
15/// @brief Provide build-specific, runtime-configurable assertion macros.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_assert
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_assert-purpose"> Purpose</a>
25/// * <a href="#bsls_assert-classes"> Classes </a>
26/// * <a href="#bsls_assert-macros"> Macros </a>
27/// * <a href="#bsls_assert-description"> Description </a>
28/// * <a href="#bsls_assert-defensive-programming"> Defensive Programming (DP) </a>
29/// * <a href="#bsls_assert-assertion-semantics"> Assertion Semantics </a>
30/// * <a href="#bsls_assert-assertion-modes"> Assertion Modes </a>
31/// * <a href="#bsls_assert-review-mode"> Review Mode </a>
32/// * <a href="#bsls_assert-detailed-behavior"> Detailed Behavior </a>
33/// * <a href="#bsls_assert-selecting-which-assert-macro-to-use"> Selecting Which ASSERT Macro to Use </a>
34/// * <a href="#bsls_assert-assertion-and-review-levels"> Assertion and Review Levels </a>
35/// * <a href="#bsls_assert-runtime-configurable-assertion-failure-behavior"> Runtime-Configurable Assertion-Failure Behavior </a>
36/// * <a href="#bsls_assert-exception-throwing-failure-handlers-and-bsls-assertfailurehandlerguard"> Exception-Throwing Failure Handlers and bsls::AssertFailureHandlerGuard </a>
37/// * <a href="#bsls_assert-assertion-handler-policy"> Assertion Handler Policy </a>
38/// * <a href="#bsls_assert-configuring-an-exception-to-the-assertion-handler-policy"> Configuring an Exception to the Assertion Handler Policy </a>
39/// * <a href="#bsls_assert-legacy-handler-functions"> Legacy Handler Functions </a>
40/// * <a href="#bsls_assert-assertions-in-header-files"> Assertions in Header Files (Mixing Build Options Across Translation Units) </a>
41/// * <a href="#bsls_assert-conditional-compilation"> Conditional Compilation </a>
42/// * <a href="#bsls_assert-validating-disabled-macro-expressions"> Validating Disabled Macro Expressions </a>
43/// * <a href="#bsls_assert-language-level-contracts"> Language-Level Contracts </a>
44/// * <a href="#bsls_assert-usage"> Usage </a>
45/// * <a href="#bsls_assert-example-1-using-bsls_assert-bsls_assert_safe-and-bsls_assert_opt"> Example 1: Using BSLS_ASSERT, BSLS_ASSERT_SAFE, and BSLS_ASSERT_OPT </a>
46/// * <a href="#bsls_assert-example-2-when-and-how-to-call-the-invokehandler-method-directly"> Example 2: When and How to Call the invokeHandler Method Directly </a>
47/// * <a href="#bsls_assert-example-3-runtime-configuration-of-the-bsls-assert-facility"> Example 3: Runtime Configuration of the bsls::Assert Facility </a>
48/// * <a href="#bsls_assert-example-4-creating-a-custom-assertion-handler"> Example 4: Creating a Custom Assertion Handler </a>
49/// * <a href="#bsls_assert-example-5-using-the-bsls-assertfailurehandlerguard"> Example 5: Using the bsls::AssertFailureHandlerGuard </a>
50/// * <a href="#bsls_assert-example-6-using-assert-macros-along-with-bde_build_target_safe_2"> Example 6: Using (BSLS) "ASSERT" Macros Along With BDE_BUILD_TARGET_SAFE_2 </a>
51/// * <a href="#bsls_assert-example-7-conditional-compilation-associated-with-enabled-assertion-levels"> Example 7: Conditional Compilation Associated with Enabled Assertion Levels </a>
52/// * <a href="#bsls_assert-example-8-conditional-compilation-of-support-functions"> Example 8: Conditional Compilation of Support Functions </a>
53/// * <a href="#bsls_assert-example-9-conditional-compilation-of-support-code"> Example 9: Conditional Compilation of Support Code </a>
54/// * <a href="#bsls_assert-example-10-asserting-a-branch-is-unreachable"> Example 10: Asserting a Branch Is Unreachable </a>
55///
56/// # Purpose {#bsls_assert-purpose}
57/// Provide build-specific, runtime-configurable assertion macros.
58///
59/// # Classes {#bsls_assert-classes}
60///
61/// - bsls::Assert: namespace for "assert" management functions
62/// - bsls::AssertFailureHandlerGuard: scoped guard for changing handlers safely
63/// - bsls::AssertViolation: attributes describing a failed assertion
64///
65/// # Macros {#bsls_assert-macros}
66///
67/// - BSLS_ASSERT: runtime check typically enabled in non-opt build modes
68/// - BSLS_ASSERT_SAFE: runtime check typically only enabled in safe build modes
69/// - BSLS_ASSERT_OPT: runtime check typically enabled in all build modes
70/// - BSLS_ASSERT_INVOKE: for directly invoking the current failure handler
71/// - BSLS_ASSERT_INVOKE_NORETURN: direct invocation always marked to not return
72/// - BSLS_ASSERT_UNREACHABLE: mark unreachable code path, enabled like ASSERT
73/// - BSLS_ASSERT_SAFE_UNREACHABLE: unreachable code path, enabled like SAFE
74/// - BSLS_ASSERT_OPT_UNREACHABLE: unreachable code path, enabled like OPT
75///
76/// @see bsls_review, bsls_asserttest
77///
78/// # Description {#bsls_assert-description}
79/// This component provides three "assert-like" macros,
80/// `BSLS_ASSERT`, `BSLS_ASSERT_SAFE`, and `BSLS_ASSERT_OPT`, that can be used
81/// to enable optional *redundant* runtime checks in corresponding build modes.
82/// If an assertion argument evaluates to 0, a runtime-configurable "handler"
83/// function is invoked with a `bsls::AssertViolation`, a value-semantic class
84/// that encapsulates the current filename, line number, level of failed check,
85/// and (0-valued expression) argument text.
86///
87/// The class `bsls::Assert` provides functions for manipulating the globally
88/// configured "handler". A scoped guard for setting and restoring the assert
89/// handler is provided by `bsls::AssertFailureHandlerGuard`.
90///
91/// An additional macro, `BSLS_ASSERT_INVOKE`, is provided for direct invocation
92/// of the current assertion failure handler. This macro is always enabled
93/// (i.e., regardless of build mode).
94///
95/// ## Defensive Programming (DP) {#bsls_assert-defensive-programming}
96///
97///
98/// Although there is no one agreed-upon definition, in this context we will use
99/// the term *Defensive* *Programming* (DP) to mean any attempt by the component
100/// author to provide (optional) runtime validation of the preconditions (or
101/// invariants) defined in the function-level documentation (contract) for that
102/// component. Note that DP is intended to help expose defects early in the
103/// development process, and *never* to mask or recover from them in production.
104///
105/// Calling a function without satisfying its preconditions results in
106/// *undefined* *behavior*. Detecting and reporting undefined behavior due to
107/// client misuse can sometimes be very helpful at identifying subtle errors.
108/// Additionally, we may choose to embed redundant (i.e., logically superfluous)
109/// runtime checks -- both as a form of active documentation, and also to help
110/// expose our own, latent coding errors that have escaped detection during
111/// testing. In either case, these *defensive* (and other) runtime checks can
112/// add significant overhead. Hence, this extra runtime overhead should not
113/// necessarily be incorporated for every build target and assertion mode (see
114/// "Build Modes" below). Moreover, the extent of these checks may change
115/// (i.e., for a particular build mode) from one release to the next.
116/// Therefore, any defensive (or other redundant) checks provided for a
117/// particular build mode are *NEVER* part of the function-level contract -- and
118/// remain solely what is known as a *Quality-of-Implementation* (QoI) issue.
119///
120/// ## Assertion Semantics {#bsls_assert-assertion-semantics}
121///
122///
123/// There are three important aspects of assertions: (1) **Every assertion
124/// is redundant**; it is essential that if all assertions are compiled
125/// out of a program that is defect-free, apart from improved runtime
126/// performance, the program behaves identically. Hence, (2) **each**
127/// !boolean-valued! **assert argument must have no**
128/// !side-effects!. Finally, (3) **assertions do not affect binary
129/// compatibility**; hence, translation units with different
130/// assertion levels (but not necessarily build targets) can safely be combined
131/// into a single program (see "Build Modes" and "Assertions in Header Files"
132/// below). Note that the build target `BDE_BUILD_TARGET_SAFE_2` does permit
133/// binary incompatibility for conditionally compiled source code, but there is
134/// no corresponding `BSLS_ASSERT_SAFE_2` assertion macro (see @ref bsls_assert-usage ).
135///
136/// ## Assertion Modes {#bsls_assert-assertion-modes}
137///
138///
139/// Depending on the build, assertion macros can expand in 3 different ways:
140///
141/// 1. A @ref bsls_assert macro is "enabled in assert mode", or simply "enabled" if
142/// it expands to check its predicate and call the assert failure handler
143/// when it is false.
144/// 2. A @ref bsls_assert macro is "enabled in review mode", or simply "in review
145/// mode" if it expands to check its predicate and call the *review* failure
146/// handler when it is false. This is identical to a @ref bsls_review macro of
147/// the same level when it is enabled.
148/// 3. A @ref bsls_assert macro is "disabled" if it expands to do nothing,
149/// producing no executed code in the compiled program.
150///
151/// ## Review Mode {#bsls_assert-review-mode}
152///
153///
154/// The ability to enable assertions in review mode allows clients to easily and
155/// safely test, in a production environment, whether assertions having a lower
156/// threshold than what they currently have deployed are being triggered
157/// (without terminating the application). It is intended as an interim step
158/// towards lowering the assertion level threshold for an existing application.
159/// See @ref bsls_review for a more detailed description of the behavior of
160/// assertions in review mode and suggested workflows for using this behavior.
161///
162/// ## Detailed Behavior {#bsls_assert-detailed-behavior}
163///
164///
165/// If an assertion fires (i.e., due to a 0-valued expression argument in an
166/// assert macro that is enabled or in review mode), there is a violation of the
167/// contract that the assertion is checking. If the assertion is enabled, the
168/// goal of the assertion is to report the precise location and nature of the
169/// defect *quickly* and *loudly* and prevent continued execution of the calling
170/// function past that point. If the assertion is in review mode then the
171/// behavior will match the corresponding @ref bsls_review macro and execution
172/// might continue, which has a priority of just logging the failure location.
173///
174/// When enabled, the assert macros will all do essentially the same thing: Each
175/// macro tests the predicate expression `X`, and if `!(X)` is `true`, invokes
176/// the currently installed assertion failure handler. An instance of
177/// `bsls::AssertViolation` will be created and populated with a textual
178/// rendering of the predicate (`#X`), the current `__FILE__`, the current
179/// `__LINE__`, and a string representing which particular type of assertion has
180/// failed. This `violation` is then passed to the currently installed
181/// assertion failure handler (a function pointer with the type
182/// `bsls::Assert::ViolationHandler` having the signature:
183/// @code
184/// void(const bsls::AssertViolation&);
185/// @endcode
186///
187/// On some (currently experimental) platforms with support for some form of the
188/// upcoming language-level contract facilities there is also the ability to
189/// configure the assertion macros to introduce an assumption of the truth of
190/// their predicate. With this option the predicate will not neccesarily even
191/// be evaluated, and if it were to return false the compiler will treat the
192/// situation as undefined behavior ("impossible"). This mode for assertions
193/// can lead to improved code generation, but be aware that the potential
194/// downside of being wrong about the truth of your assertions is unbounded, and
195/// so deploying applications built with any assertions assumed should be done
196/// with great care - there are no guarantees about anything a program will do
197/// when an assumed assertion is violated.
198///
199/// ## Selecting Which ASSERT Macro to Use {#bsls_assert-selecting-which-assert-macro-to-use}
200///
201///
202/// The choice of which specific macro to use is governed primarily by the
203/// impact that enabling the assertion (in either assert mode or review mode)
204/// will have on the runtime performance of the function, and in some cases on
205/// the size of the function.
206///
207/// 1. `BSLS_ASSERT_SAFE` - This macro should be reserved for tests incurring an
208/// expensive change to the performance of a function, either a very high
209/// constant time increase in execution time of the function, or an increase
210/// in the algorithmic complexity of a function. Note especially that a
211/// change in algorithmic complexity breaks the documented contract of many
212/// functions (e.g., an `O(n)` check in a function with a documented
213/// `O(log(n))` runtime speed) and so checks with that level of cost should
214/// be reserved for diagnostic use in "safe" builds.
215/// 2. `BSLS_ASSERT` - For "inexpensive" checks with only a constant factor
216/// overhead. The majority of checks should fall into this category.
217/// 3. `BSLS_ASSERT_OPT` - For "negligible" checks that have little to no
218/// measurable overhead on a function. This will often be the case for
219/// argument checking in larger functions, or very simple checks in smaller
220/// functions. Keep in mind that these checks will be enabled in all
221/// typically deployed build modes, so they should be reserved for larger
222/// functions and functions that will not be called in highly performance
223/// critical code.
224///
225/// ## Assertion and Review Levels {#bsls_assert-assertion-and-review-levels}
226///
227///
228/// There are a few macros available to control which of the @ref bsls_assert
229/// macros are disabled, enabled in review mode, or enabled in assert mode (see
230/// {Assertion Modes} above). These macros are for the compilation and build
231/// environment to provide and are not themselves defined by BDE code -- e.g.,
232/// by supplying one or more of these macros with `-D` options on the compiler
233/// command line. In general, these macros are used to determine an
234/// `ASSERT_LEVEL` that can be (from most aggressive/optimized to safest)
235/// `ASSUME_SAFE`, `ASSUME_ASSERT`, `ASSUME_OPT`, `NONE`, `ASSERT_OPT`,
236/// `ASSERT`, or `ASSERT_SAFE`. Separately, a `REVIEW_LEVEL` is determined that
237/// can be `NONE`, `REVIEW_OPT`, `REVIEW`, or `REVIEW_SAFE`. Depending on these
238/// levels, the various @ref bsls_assert macros will be enabled, in review mode,
239/// assumed, or disabled. Macros up to the assert level will be enabled. If
240/// the review level is higher than the assert level then macros up to the
241/// review level (and above the assert level) will be enabled in review mode.
242/// Finally, macros higher than both the review level and the assert level will
243/// be disabled. If the review level is `NONE` and the assert level is set to
244/// one of the assume levels, then macros that would be disabled up to the
245/// assumed level are instead assumed. If there is a review level set then no
246/// macros will ever be assumed. The following table illustrates this:
247/// @code
248/// ===========================================
249/// Macro Instantiation Based on Review Level
250/// ===========================================
251/// ENABLED - Assertion is enabled (in "assert mode")
252/// REVIEW - Assertion is enabled (in "review mode")
253/// ASSUMED - Assertion is assumed (if supported)
254/// <blank> - Assertion is ignored
255/// -----------BSLS... LEVELS---------- ----------BSLS_.. MACROS---------
256/// BSLS_ASSERT_LEVEL BSLS_REVIEW_LEVEL ASSERT_OPT ASSERT ASSERT_SAFE
257/// ----------------- ----------------- ---------- ---------- -----------
258/// ASSUME_SAFE NONE ASSUMED ASSUMED ASSUMED
259/// ASSUME_ASSERT NONE ASSUMED ASSUMED
260/// ASSUME_OPT NONE ASSUMED
261/// NONE NONE
262/// NONE (or ASSUME*) REVIEW_OPT REVIEW
263/// NONE (or ASSUME*) REVIEW REVIEW REVIEW
264/// NONE (or ASSUME*) REVIEW_SAFE REVIEW REVIEW REVIEW
265/// ASSERT_OPT NONE ENABLED
266/// ASSERT_OPT REVIEW_OPT ENABLED
267/// ASSERT_OPT REVIEW ENABLED REVIEW
268/// ASSERT_OPT REVIEW_SAFE ENABLED REVIEW REVIEW
269/// ASSERT NONE ENABLED ENABLED
270/// ASSERT REVIEW_OPT ENABLED ENABLED
271/// ASSERT REVIEW ENABLED ENABLED
272/// ASSERT REVIEW_SAFE ENABLED ENABLED REVIEW
273/// ASSERT_SAFE NONE ENABLED ENABLED ENABLED
274/// ASSERT_SAFE REVIEW_OPT ENABLED ENABLED ENABLED
275/// ASSERT_SAFE REVIEW ENABLED ENABLED ENABLED
276/// ASSERT_SAFE REVIEW_SAFE ENABLED ENABLED ENABLED
277/// @endcode
278/// See @ref bsls_review for the logic that determines the review level. The
279/// logic that determines the assertion level checks a few different macros.
280/// The first check is for one of the 7 mutually exclusive `BSLS_ASSERT_LEVEL`
281/// macros that can explicitly set the assert level:
282/// @code
283/// MACRO BSLS_ASSERT_LEVEL
284/// ----- ----------------
285/// BSLS_ASSERT_LEVEL_ASSUME_SAFE ASSUME_SAFE
286/// BSLS_ASSERT_LEVEL_ASSUME_ASSERT ASSUME_ASSERT
287/// BSLS_ASSERT_LEVEL_ASSUME_OPT ASSUME_OPT
288/// BSLS_ASSERT_LEVEL_NONE NONE
289/// BSLS_ASSERT_LEVEL_ASSERT_OPT ASSERT_OPT
290/// BSLS_ASSERT_LEVEL_ASSERT ASSERT
291/// BSLS_ASSERT_LEVEL_ASSERT_SAFE ASSERT_SAFE
292/// @endcode
293/// If none of these are defined, the assert level is determined by the build
294/// mode. With "safer" build modes we incorporate higher level defensive
295/// checks. A particular build mode is implied by the relevant (BDE) build
296/// targets that are defined at compilation (preprocessing) time. The following
297/// table shows the three (BDE) build targets that can affect the assertion and
298/// review levels:
299/// @code
300/// (BDE) Build Targets
301/// -----------------------
302/// (A) BDE_BUILD_TARGET_SAFE_2
303/// (B) BDE_BUILD_TARGET_SAFE
304/// (C) BDE_BUILD_TARGET_OPT
305/// @endcode
306/// *Any* of the 8 possible combinations of the three build targets is valid:
307/// e.g., `BDE_BUILD_TARGET_OPT` and `BDE_BUILD_TARGET_SAFE_2` may both be
308/// defined. The following table shows the assert level that is set depending
309/// on which combination of build target macros have been set:
310/// @code
311/// =========================================================
312/// "ASSERT" Level Set With no Level-Overriding Flags defined
313/// =========================================================
314/// --- BDE_BUILD_TARGET ---- BSLS_ASSERT_LEVEL
315/// _SAFE_2 _SAFE _OPT
316/// ------- ------- ------- -----------------
317/// ASSERT
318/// DEFINED ASSERT_OPT
319/// DEFINED ASSERT_SAFE
320/// DEFINED DEFINED ASSERT_SAFE
321/// DEFINED ASSERT_SAFE
322/// DEFINED DEFINED ASSERT_SAFE
323/// DEFINED DEFINED ASSERT_SAFE
324/// DEFINED DEFINED DEFINED ASSERT_SAFE
325/// @endcode
326/// As the table above illustrates, with no build target explicitly defined the
327/// assert level defaults to `ASSERT`. If only `BDE_BUILD_TARGET_OPT` is
328/// defined, the assert level will be set to `ASSERT_OPT`. If either
329/// `BDE_BUILD_TARGET_SAFE` or `BDE_BUILD_TARGET_SAFE_2` is defined then the
330/// assert level is set to `ASSERT_SAFE` and ALL assert macros will be enabled.
331///
332/// ## Runtime-Configurable Assertion-Failure Behavior {#bsls_assert-runtime-configurable-assertion-failure-behavior}
333///
334///
335/// In addition to the three (BSLS) "ASSERT" macros, `BSLS_ASSERT`,
336/// `BSLS_ASSERT_SAFE`, and `BSLS_ASSERT_OPT`, and the immediate invocation
337/// macro `BSLS_ASSERT_INVOKE`, this component provides (1) an `invokeHandler`
338/// method used (primarily) to implement these "ASSERT" macros and enable their
339/// runtime configuration, (2) administration methods to configure, at runtime,
340/// the behavior resulting from an assertion failure (i.e., by installing an
341/// appropriate assertion-failure handler function), and (3) a suite of standard
342/// ("off-the-shelf") assertion-failure handler functions, to be installed via
343/// the administrative methods (if desired), and invoked by the `invokeHandler`
344/// method on an assertion failure.
345///
346/// When an enabled assertion fails, the currently installed *failure* *handler*
347/// ("callback") function is invoked. The default handler is the (`static`)
348/// `bsls::Assert::failByAbort` method; a user may replace this default handler
349/// by using the (`static`) `bsls::Assert::setViolationHandler` administrative
350/// method and passing it (the address of) a function whose signature conforms
351/// to the `bsls::Assert::ViolationHandler` `typedef`. This handler may be one
352/// of the other handler methods provided in `bsls::Assert`, or a new "custom"
353/// function, written by the user (see @ref bsls_assert-usage ).
354///
355/// ## Exception-Throwing Failure Handlers and bsls::AssertFailureHandlerGuard {#bsls_assert-exception-throwing-failure-handlers-and-bsls-assertfailurehandlerguard}
356///
357///
358/// Among the failure handlers provided is `bsls::Assert::failByThrow`, which
359/// throws a `bsls::AssertTestException` object. Throwing an exception,
360/// however, is not safe in all environments and deliberately aborting is more
361/// useful in a debugging context than throwing an unhandled exception. Hence,
362/// in order for an `bsls::AssertTestException` object to be thrown on an
363/// assertion failure, the user must first install the
364/// `bsls::Assert::failByThrow` handler (or another exception-throwing handler)
365/// explicitly.
366///
367/// Note that an object of type `bsls::AssertFailureHandlerGuard` can be used to
368/// temporarily set an exception-throwing handler within a `try` block,
369/// automatically restoring the previous handler when the `try` block exits (see
370/// @ref bsls_assert-usage ).
371///
372/// ## Assertion Handler Policy {#bsls_assert-assertion-handler-policy}
373///
374///
375/// Bloomberg policy is that (by default) tasks may not install an assertion
376/// handler that returns control to the point immediately following the
377/// detection of a failed assertion. So an assertion handler may, for example,
378/// terminate the task or throw an exception, but may not log the problem and
379/// return. @ref bsls_assert , by default, enforces that policy by terminating the
380/// task if an installed assertion handler function chooses to returns normally.
381///
382/// ### Configuring an Exception to the Assertion Handler Policy {#bsls_assert-configuring-an-exception-to-the-assertion-handler-policy}
383///
384///
385/// @ref bsls_assert provides a two-part mechanism to permit returning after the
386/// detection of failed assertions.
387///
388/// It is a violation of Bloomberg policy to modify this default configuration
389/// without permission from senior management. (Internal Bloomberg users should
390/// contact the BDE team if you feel your application needs an exception to this
391/// policy).
392///
393/// The intention is to provide a means to override the assertion failure policy
394/// that can be enabled quickly, but requires the explicit (and obvious) choice
395/// from both the owner of the application's `main` function, and the person
396/// responsible for building the application. In order to enable a policy
397/// exception, `permitOutOfPolicyReturningFailureHandler` must be called, and
398/// the task must be linked with a special build of `bsls_assert.o` (in which
399/// the `k_permitOutOfPolicyReturningAssertionBuildKey` constant has the value
400/// "bsls-PermitOutOfPolicyReturn").
401///
402/// ## Legacy Handler Functions {#bsls_assert-legacy-handler-functions}
403///
404///
405/// Prior to the introduction of `bsls::AssertViolation`, the signature for
406/// `bsls::Assert::ViolationHandler` was this:
407/// @code
408/// void(const char*, const char*,int)
409/// @endcode
410/// This signature for a handler is still supported (though deprecated) under
411/// its original name `bsls::Assert::Handler`. Overloads that take a
412/// `bsls::Assert::Handler` exist for `bsls::AssertFailureHandler` and the
413/// constructor for `bsls::AssertFailureHandlerGuard`, so code that uses the old
414/// handler signature should work without changes.
415///
416/// If a legacy handler is set as the current handler, the function
417/// `bsls::Assert::failureHandler()` will return a pointer to that function,
418/// while `bsls::Assert::violationHandler()` will return an internal function
419/// that extracts the appropriate arguments from the generated
420/// `bsls::AssertViolation` object and passes them to the installed `Handler`.
421///
422/// ## Assertions in Header Files (Mixing Build Options Across Translation Units) {#bsls_assert-assertions-in-header-files}
423///
424///
425/// Mixing build modes across translation units, although not strictly
426/// conformant with the C++ language standard, is permissible in practice;
427/// however, the defensive checks that are enabled may be unpredictable. The
428/// *one-definition* *rule* states that if there are multiple definitions of an
429/// object or function within a program, these definitions *must* be identical
430/// or else the program is *ill-formed*. Unfortunately, definitions in header
431/// files may not be identical across object (`.o`) files if the build targets
432/// or assertion-level flags defined during translation (preprocessing) are not
433/// the same.
434///
435/// For example, consider an `inline` function that sets the width of a `Square`
436/// and optionally checks for (defends against) a negative `width` argument:
437/// @code
438/// // our_square.h
439///
440/// inline
441/// void Square::setWidth(int width)
442/// {
443/// BSLS_ASSERT_SAFE(width >= 0);
444///
445/// d_width = width;
446/// }
447/// @endcode
448/// Now consider a client that uses this `setWidth` method:
449/// @code
450/// // my_client.cpp
451///
452/// void f()
453/// {
454/// Square s;
455/// s.setWidth(-5);
456/// }
457/// @endcode
458/// We can build the @ref our_square component in "safe mode" -- e.g., by
459/// incorporating `-DBSLS_ASSERT_LEVEL_ASSERT_SAFE` on the (Unix) command line.
460/// Notice, however, that building client software against a version of
461/// `our_square.o` compiled in "safe mode" does *not* ensure that all of the
462/// `BSLS_ASSERT_SAFE` macros will be active (will instantiate); instead, the
463/// client's build mode will (most likely) govern those instantiations of the
464/// `BSLS_ASSERT_SAFE` macro located within the library. The only way to ensure
465/// that all of the `BSLS_ASSERT_SAFE` macros instantiate is to build the
466/// *client* as well as the library software in "safe mode".
467///
468/// Inline functions are not the only source of multiple inconsistent
469/// definitions. Consider a non-`inline` method `reserveCapacity` on a `List`
470/// template, parameterized by element `TYPE`:
471/// @code
472/// // our_list.h
473///
474/// template <class TYPE>
475/// void List<TYPE>::reserveCapacity(int numElements)
476/// {
477/// BSLS_ASSERT(numElements >= 0);
478/// // ...
479/// }
480/// @endcode
481/// Each different translation unit that invokes `reserveCapacity` potentially
482/// generates another instantiation of this function template. Those
483/// translation units that are compiled in "debug mode" (or "safe mode") --
484/// e.g., with `BSLS_ASSERT_LEVEL_ASSERT` (or `BSLS_ASSERT_LEVEL_ASSERT_SAFE`)
485/// defined -- will incorporate code corresponding to each use of the
486/// `BSLS_ASSERT` macro therein; the rest will not. Which one of these template
487/// instantiations the linker uses in the final program is undefined and highly
488/// unpredictable.
489///
490/// The bottom line is that, unless clients of a library are compiled with (at
491/// least) the same level of assertion enabling as the library itself, not all
492/// of the library's defensive checking (for the assertion-level for which the
493/// library was compiled) will necessarily be incorporated into the client code.
494/// Similarly, compiling a client in a higher-level of defensive checking (e.g.,
495/// "safe mode") than the library was compiled (e.g., "debug mode") may result
496/// in additional defensive checks beyond what the library author intended for
497/// the mode (e.g., "debug mode") in which the library was compiled.
498///
499/// Note that all build modes (except for when `BDE_BUILD_TARGET_SAFE_2` is
500/// defined, see below) are required to be binary compatible (e.g., fields
501/// cannot be added to the middle of a `struct`). Since a component's contract
502/// makes no explicit promise about what checking will occur, that contract is
503/// not violated when different parts of a program are compiled with different
504/// levels of assertion-enabling build options. The only consequence is that a
505/// smaller (or larger) number of defensive checks may be active than might
506/// otherwise be expected.
507///
508/// ## Conditional Compilation {#bsls_assert-conditional-compilation}
509///
510///
511/// To recap, there are three (mutually compatible) general **build targets**:
512/// * `BDE_BUILD_TARGET_OPT`
513/// * `BDE_BUILD_TARGET_SAFE`
514/// * `BDE_BUILD_TARGET_SAFE_2`
515///
516/// seven (mutually exclusive) component-specific **assertion levels**:
517/// * `BSLS_ASSERT_LEVEL_ASSERT_SAFE`
518/// * `BSLS_ASSERT_LEVEL_ASSERT`
519/// * `BSLS_ASSERT_LEVEL_ASSERT_OPT`
520/// * `BSLS_ASSERT_LEVEL_NONE`
521/// * `BSLS_ASSERT_LEVEL_ASSUME_OPT`
522/// * `BSLS_ASSERT_LEVEL_ASSUME_ASSERT`
523/// * `BSLS_ASSERT_LEVEL_ASSUME_SAFE`
524///
525/// and four (mutually exclusive) component-specific **review levels**:
526/// * `BSLS_REVIEW_LEVEL_REVIEW_SAFE`
527/// * `BSLS_REVIEW_LEVEL_REVIEW`
528/// * `BSLS_REVIEW_LEVEL_REVIEW_OPT`
529/// * `BSLS_REVIEW_LEVEL_NONE`
530///
531/// The above macros can be defined (externally) by the build environment to
532/// affect which of the three **assert macros**:
533/// * `BSLS_ASSERT_SAFE(boolean-valued expression)`
534/// * `BSLS_ASSERT(boolean-valued expression)`
535/// * `BSLS_ASSERT_OPT(boolean-valued expression)`
536///
537/// will be enabled in assert mode, which will be in review mode, which will be
538/// assumed, and which will be disabled.
539///
540/// The public interface of this component also explicitly provides a number of
541/// additional intermediate macros to identify how the various `BSLS_ASSERT`
542/// macros have been instantiated. These each exist for each level and have the
543/// following suffixes and meanings:
544/// * `IS_ACTIVE`: Defined if the corresponding level is enabled in assert or
545/// review mode. For example, `BSLS_ASSERT_SAFE_IS_ACTIVE` is defined if
546/// (and only if) the conditions expressed using `BSLS_ASSERT_SAFE` will be
547/// checked at runtime (either as assertions or reviews).
548/// * `IS_REVIEW`: Defined if the corresponding level is enabled in review
549/// mode.
550/// * `IS_ASSUMED`: Defined if the corresponding level is assumed.
551/// * `IS_USED`: Defined if assert expressions for the corresponding level need
552/// to be valid (i.e., if they are "ODR-used"). For example,
553/// `BSLS_ASSERT_SAFE_IS_USED` is defined if (and only if) the conditions
554/// expressed using `BSLS_ASSERT_SAFE` will be compiled. Note that this is a
555/// super-set of the cases where `BSLS_ASSERT_SAFE_IS_ACTIVE` will be
556/// defined, which is when the conditions will be checked at runtime, while
557/// `BSLS_ASSERT_SAFE_IS_USED` is also defined if the conditions are assumed
558/// or if `BSLS_ASSERT_VALIDATE_DISABLED_MACROS` is defined.
559///
560/// Putting that together, these 3 macros are defined if the corresponding macro
561/// is in assert or review mode - and thus the expression will be checked and a
562/// violation handler will be invoked on failure:
563/// * `BSLS_ASSERT_SAFE_IS_ACTIVE`
564/// * `BSLS_ASSERT_IS_ACTIVE`
565/// * `BSLS_ASSERT_OPT_IS_ACTIVE`
566///
567/// These three are defined if the corresponding macro is in review mode - and
568/// thus the expression will be checked and the review violation handler will be
569/// invoked on failure. These will be defined when the review level has been
570/// set to a level higher than the assert level:
571/// * `BSLS_ASSERT_SAFE_IS_REVIEW`
572/// * `BSLS_ASSERT_IS_REVIEW`
573/// * `BSLS_ASSERT_OPT_IS_REVIEW`
574///
575/// These three are defined if the corresponding macro is being assumed, and it
576/// will be hard undefined behavior to violate these expressions:
577/// * `BSLS_ASSERT_SAFE_IS_ASSUMED`
578/// * `BSLS_ASSERT_IS_ASSUMED`
579/// * `BSLS_ASSERT_OPT_IS_ASSUMED`
580///
581/// Finally, three more macros with the `IS_USED` suffix are defined when the
582/// expression for the corresponding macro is going to be compiled. This will
583/// be true for macros in assert, review or assumed modes, and it will be true
584/// for all macros if `BSLS_ASSERT_VALIDATE_DISABLED_MACROS` has been defined.
585/// * `BSLS_ASSERT_SAFE_IS_USED`
586/// * `BSLS_ASSERT_IS_USED`
587/// * `BSLS_ASSERT_OPT_IS_USED`
588///
589/// Note that any of the `IS_ACTIVE`, `IS_REVIEW`, and `IS_ASSUMED` macros being
590/// defined will imply that the corresponding `IS_USED` macro is also defined.
591///
592/// Which of these macros to use to conditionally compile supporting code is
593/// based on when that supporting code needs to be compiled:
594/// * Use `#if defined(..._IS_USED)` when:
595/// - Writing functions that are only accessible to and needed for assertions
596/// of the corresponding level. This could be private member functions,
597/// static functions, or functions in an anonymous namespace. See
598/// {Example 8} for details on this use.
599/// * Use `#if !defined(..._IS_ACTIVE) && !defined(..._IS_ASSUMED)` when:
600/// - You are writing (test) code that will intentionally violate a contract
601/// when there is not going to be any intrinsic ill effect to that
602/// violation. Generally this should only be required when there is a need
603/// to validate out-of-contract behavior of a component from within its own
604/// test driver.
605/// * Use `#if defined(...IS_ACTIVE)` when:
606/// - You are doing negative testing and want to be sure that when you call
607/// your function out of contract that the violation handler will be
608/// invoked. See @ref bsls_asserttest for tools to do this without having
609/// to manually check these macros.
610/// - Writing redundant defensive code that should only execute when the
611/// corresponding assertions are going to be enabled. The assertion itself
612/// should also be included in the same preprocessor block. See
613/// {Example 9} for details on this use.
614/// - Note that historically this was the only macro available, and it is
615/// often used for blocks of code where the checks above would be more
616/// appropriate. This can often lead to code that fails to compile with
617/// `BSLS_ASSERT_VALIDATE_DISABLED_MACROS` enabled or which will not work
618/// correctly when assumptions are turned on.
619///
620/// See {Example 6} and {Example 7}, respectively, for how
621/// `BDE_BUILD_TARGET_SAFE_2` and intermediate assertion predicate macros, such
622/// as `BSLS_ASSERT_SAFE_IS_ACTIVE` (and even `BSLS_ASSERT_OPT_IS_ACTIVE`), can
623/// be used profitably in practice.
624///
625/// ## Validating Disabled Macro Expressions {#bsls_assert-validating-disabled-macro-expressions}
626///
627///
628/// An additional external macro, `BSLS_ASSERT_VALIDATE_DISABLED_MACROS`, can be
629/// defined to control the compile time behavior of @ref bsls_assert . Enabling
630/// this macro configures all **disabled** assert macros to still instantiate
631/// their predicates (in a non-evaluated context) to be sure that the predicate
632/// is still syntactically valid. This can be used to ensure assertions that
633/// are rarely enabled have valid expressions.
634///
635/// ## Language-Level Contracts {#bsls_assert-language-level-contracts}
636///
637///
638/// Contracts were proposed, accepted into the draft C++20 standard, and then
639/// removed. Implementations of that facility exist and it is expected future
640/// implementations will begin to arrive as work on new proposals comes to
641/// fruition. Defining the macro `BSLS_ASSERT_USE_CONTRACTS` will cause all
642/// `BSLS_ASSERT` (and, if possible, `BSLS_REVIEW`) macros to go through the
643/// language-level contract implementation if it is available (currently only on
644/// an experimental version of the gcc-compiler), otherwise a diagnostic will be
645/// issued.
646///
647/// Note that mixing builds that do and do not use `BSLS_ASSERT_USE_CONTRACTS`
648/// is not supported. Attempting to link against a library bult with a
649/// different mode for this option will cause a link-time error.
650///
651/// ## Usage {#bsls_assert-usage}
652///
653///
654/// The following examples illustrate (1) when to use each of the three kinds of
655/// (BSLS) "ASSERT" macros, (2) when and how to call the `invokeHandler` method
656/// directly, (3) how to configure, at runtime, the behavior resulting from an
657/// assertion failure using "off-the-shelf" handler methods, (4) how to create
658/// your own custom assertion-failure handler function, (5) proper use of
659/// `bsls::AssertFailureHandlerGuard` to install, temporarily, an
660/// exception-producing assert handler, (6) how "ASSERT" macros would be used in
661/// conjunction with portions of the source code (affecting binary
662/// compatibility) that are incorporated only when `BDE_BUILD_TARGET_SAFE_2` is
663/// defined, and (7) how assertion predicates (e.g.,
664/// `BSLS_ASSERT_SAFE_IS_ACTIVE`) are used to conditionally compile additional
665/// (redundant) defensive source code (not affecting binary compatibility)
666/// precisely when the corresponding (BSLS) "ASSERT" macro (e.g.,
667/// `BSLS_ASSERT_SAFE`) is active.
668///
669/// ### Example 1: Using BSLS_ASSERT, BSLS_ASSERT_SAFE, and BSLS_ASSERT_OPT {#bsls_assert-example-1-using-bsls_assert-bsls_assert_safe-and-bsls_assert_opt}
670///
671///
672/// This component provides three different variants of (BSLS) "ASSERT" macros.
673/// This first usage example illustrates how one might select each of the
674/// particular variants, based on the runtime cost of the defensive check
675/// relative to that of the useful work being done.
676///
677/// Use of the `BSLS_ASSERT_SAFE` macro is often appropriate when the defensive
678/// check occurs within the body of an `inline` function. The
679/// `BSLS_ASSERT_SAFE` macro minimizes the impact on runtime performance as it
680/// is instantiated only when requested (i.e., by building in "safe mode"). For
681/// example, consider a light-weight point class `Kpoint` that maintains `x` and
682/// `y` coordinates in the range `[-1000 .. 1000]`:
683/// @code
684/// my_kpoint.h
685///
686/// class Kpoint {
687/// short int d_x;
688/// short int d_y;
689/// public:
690///
691/// /// ...
692/// /// The behavior is undefined unless `-1000 <= x <= 1000` and
693/// /// `-1000 <= y <= 1000`.
694/// Kpoint(short int x, short int y);
695///
696/// // ...
697/// };
698///
699/// ...
700/// @endcode
701/// Since the cost of validation here is significant compared with the useful
702/// work being done, we might choose to implement defensive checks using
703/// `BSLS_ASSERT_SAFE` as follows:
704/// @code
705/// ...
706///
707/// inline
708/// Kpoint::Kpoint(short int x, short int y)
709/// : d_x(x)
710/// , d_y(y)
711/// {
712/// BSLS_ASSERT_SAFE(-1000 <= x); BSLS_ASSERT_SAFE(x <= 1000);
713/// BSLS_ASSERT_SAFE(-1000 <= y); BSLS_ASSERT_SAFE(y <= 1000);
714/// }
715/// @endcode
716/// For more substantial (non-`inline`) functions, we would be more likely to
717/// use the `BSLS_ASSERT` macro because the runtime overhead due to defensive
718/// checks is likely to be much less significant. For example, consider a
719/// hash-table class that allows the client to resize the underlying table:
720/// @code
721/// my_hashtable.h
722/// ...
723///
724/// /// ...
725/// class HashTable {
726/// public:
727/// // ...
728///
729/// /// Adjust the size of the underlying hash table to be approximately
730/// /// the current number of elements divided by the specified
731/// /// `loadFactor`. The behavior is undefined unless
732/// /// `0 < loadFactor`.
733/// void resize(double loadFactor);
734/// };
735/// @endcode
736/// Since the relative runtime cost of validating the input argument is quite
737/// small (e.g., less than 10%) compared to the typical work being done, we
738/// might choose to implement the defensive check using `BSLS_ASSERT` as
739/// follows:
740/// @code
741/// my_hashtable.cpp
742/// ...
743///
744/// void HashTable::resize(double loadFactor)
745/// {
746/// BSLS_ASSERT(0 < loadFactor);
747///
748/// // ...
749/// }
750/// @endcode
751/// In some cases, the runtime cost of checking is always negligible when
752/// compared with the runtime cost of performing the useful work; moreover, the
753/// consequences of continuing in an undefined state for certain applications
754/// could be catastrophic. Instead of using `BSLS_ASSERT` in such cases, we
755/// might consider using `BSLS_ASSERT_OPT`. For example, suppose we have a
756/// financial application class `TradingSystem` that performs trades:
757/// @code
758/// my_tradingsystem.h
759/// ...
760///
761/// /// ...
762/// class TradingSystem {
763/// public:
764/// // ...
765/// @endcode
766/// Further suppose that there is a particular method `executeTrade` that takes,
767/// as a scaling factor, an integer that must be a multiple of 100 or the
768/// behavior is undefined (and might actually execute a trade):
769/// @code
770/// /// Execute the current trade using the specified `scalingFactor`.
771/// /// The behavior is undefined unless `0 <= scalingFactor` and `100`
772/// /// evenly divides `scalingFactor`.
773/// void executeTrade(int scalingFactor);
774///
775/// };
776/// @endcode
777/// Because the cost of the two checks is likely not even measurable compared to
778/// the overhead of accessing databases and executing the trade, and because the
779/// consequences of specifying a bad scaling factor are virtually unbounded, we
780/// might choose to implement these defensive checks using `BSLS_ASSERT_OPT` as
781/// follows:
782/// @code
783/// my_tradingsystem.cpp
784/// ...
785///
786/// void TradingSystem::executeTrade(int scalingFactor)
787/// {
788/// BSLS_ASSERT_OPT(0 <= scalingFactor);
789/// BSLS_ASSERT_OPT(0 == scalingFactor % 100);
790///
791/// // ...
792/// }
793/// @endcode
794/// Notice that in each case, the choice of which of the three (BSLS) "ASSERT"
795/// macros to use is governed primarily by the relative runtime cost compared
796/// with that of the useful work being done (and only secondarily by the
797/// potential consequences of continuing execution in an undefined state).
798///
799/// ### Example 2: When and How to Call the invokeHandler Method Directly {#bsls_assert-example-2-when-and-how-to-call-the-invokehandler-method-directly}
800///
801///
802/// There *may* be times (but this is yet to be demonstrated) when we might
803/// reasonably choose to unconditionally invoke the currently installed
804/// assertion-failure handler directly -- i.e., instead of via one of the three
805/// (BSLS) "ASSERT" macros provided in this component. Suppose that we are
806/// currently in the body of some function `someFunc` and, for whatever reason,
807/// feel compelled to invoke the currently installed assertion-failure handler
808/// based on some criteria other than the current build mode.
809/// `BSLS_ASSERT_INVOKE` is provided for this purpose. The call might look as
810/// follows:
811/// @code
812/// void someFunc(bool a, bool b, bool c)
813/// {
814/// bool someCondition = a && b && !c;
815///
816/// if (someCondition) {
817/// BSLS_ASSERT_INVOKE("Bad News");
818/// }
819/// }
820/// @endcode
821/// If presented with invalid arguments, `someFunc` (above) will produce output
822/// similar to the following:
823/// @code
824/// Assertion failed: Bad News, file bsls_assert.t.cpp, line 609
825/// Abort (core dumped)
826/// @endcode
827/// If a piece of code needs to be guaranteed to not return, the additional
828/// macro `BSLS_ASSERT_INVOKE_NORETURN` is also available. It behaves the same
829/// way as `BSLS_ASSERT_INVOKE`, but if the installed handler *does* return
830/// `failByAbort` will be immediately called. On supported platforms it is
831/// marked appropriately to not return to support compiler optimizations and
832/// static analysis tools.
833///
834/// Note that it is possible to use the two `INVOKE` macros with a dynamically
835/// generated string, but it is generally inadvisable to do so based on how
836/// downstream systems are likely to handle the logs produced for the triggered
837/// violation. Additional information that will be useful to diagnose a
838/// problem should be logged (using, for example, `bsls_log`) prior to using
839/// the `INVOKE` macro, and the string passed is ideally a string to identify
840/// the character of the error, not to encode additional identifying
841/// information.
842///
843/// ### Example 3: Runtime Configuration of the bsls::Assert Facility {#bsls_assert-example-3-runtime-configuration-of-the-bsls-assert-facility}
844///
845///
846/// By default, any assertion failure will result in the invocation of the
847/// `bsls::Assert::failByAbort` handler function. We can replace this behavior
848/// with that of one of the other static failure handler methods supplied in
849/// `bsls::Assert` as follows. Let's assume we are at the top of our
850/// application called `myMain` (which would typically be `main`):
851/// @code
852/// void myMain()
853/// {
854/// @endcode
855/// First observe that the default assertion-failure handler function is, in
856/// fact, `bsls::Assert::failByAbort`:
857/// @code
858/// assert(&bsls::Assert::failByAbort == bsls::Assert::violationHandler());
859/// @endcode
860/// Next, we install a new assertion-failure handler function,
861/// `bsls::Assert::failBySleep`, from the suite of "off-the-shelf" handlers
862/// provided as `static` methods of `bsls::Assert`:
863/// @code
864/// bsls::Assert::setViolationHandler(&bsls::Assert::failBySleep);
865/// @endcode
866/// Observe that `bsls::Assert::failBySleep` is the new, currently-installed
867/// assertion-failure handler:
868/// @code
869/// assert(&bsls::Assert::failBySleep == bsls::Assert::violationHandler());
870/// @endcode
871/// Note that if we were to explicitly invoke the current assertion-failure
872/// handler as follows:
873/// @code
874/// BSLS_ASSERT_INVOKE("message"); // This will hang!
875/// @endcode
876/// the program will hang since `bsls::Assert::failBySleep` repeatedly sleeps
877/// for a period of time within an infinite loop. Thus, this assertion-failure
878/// handler is useful for hanging a process so that a debugger may be attached
879/// to it.
880///
881/// We may now decide to disable the `setViolationHandler` method using the
882/// `bsls::Assert::lockAssertAdministration()` method to ensure that no one else
883/// will override our decision globally. Note, however, that the
884/// `bsls::AssertFailureHandlerGuard` is not affected, and can still be used to
885/// supplant the currently installed handler (see below):
886/// @code
887/// bsls::Assert::lockAssertAdministration();
888/// @endcode
889/// Attempting to change the currently installed handler now will fail:
890/// @code
891/// bsls::Assert::setViolationHandler(&bsls::Assert::failByAbort);
892///
893/// assert(&bsls::Assert::failByAbort != bsls::Assert::violationHandler());
894///
895/// assert(&bsls::Assert::failBySleep == bsls::Assert::violationHandler());
896/// }
897/// @endcode
898///
899/// ### Example 4: Creating a Custom Assertion Handler {#bsls_assert-example-4-creating-a-custom-assertion-handler}
900///
901///
902/// Sometimes, especially during testing, we may need to write our own custom
903/// assertion-failure handler function. The only requirements are that the
904/// function have the same prototype (i.e., the same respective parameter and
905/// return types) as the `bsls::Assert::Handle` `typedef`, and that the function
906/// should not return (i.e., it must `abort`, `exit`, `terminate`, `throw`, or
907/// hang). To illustrate, we will create a `static` method at file scope that
908/// conforms to the required structure (notice the explicit use of `std::printf`
909/// from `<cstdio>` instead of `std::cout` from `<iostream>` to avoid
910/// interaction with the C++ memory allocation layer):
911/// @code
912/// static bool globalEnableOurPrintingFlag = true;
913///
914/// /// Print the expression `comment`, `file` name, and `line` number from
915/// /// the specified `violation` to `stdout` as a comma-separated list,
916/// /// replacing null string-argument values with empty strings (unless
917/// /// printing has been disabled by the `globalEnableOurPrintingFlag`
918/// /// variable), then unconditionally abort.
919/// static
920/// void ourFailureHandler(const bsls::AssertViolation& violation)
921/// {
922/// const char *comment = violation.comment();
923/// if (!comment) {
924/// comment = "";
925/// }
926/// const char *file = violation.fileName();
927/// if (!file) {
928/// file = "";
929/// }
930/// int line = violation.lineNumber();
931/// if (globalEnableOurPrintingFlag) {
932/// std::printf("%s, %s, %d\n", comment, file, line);
933/// }
934/// std::abort();
935/// }
936/// @endcode
937/// At the top level of our application we have the following:
938/// @code
939/// void ourMain()
940/// {
941/// @endcode
942/// First, let's observe that we can assign this new function to a function
943/// pointer of type `bsls::Assert::Handler`:
944/// @code
945/// bsls::Assert::ViolationHandler f = &ourFailureHandler;
946/// @endcode
947/// Now we can install it just as we would any other handler:
948/// @code
949/// bsls::Assert::setViolationHandler(&ourFailureHandler);
950/// @endcode
951/// We can now invoke the default handler directly:
952/// @code
953/// BSLS_ASSERT_INVOKE("str1");
954/// }
955/// @endcode
956/// With the resulting output something like as follows:
957/// @code
958/// str1, my_file.cpp, 17
959/// Abort (core dumped)
960/// @endcode
961///
962/// ### Example 5: Using the bsls::AssertFailureHandlerGuard {#bsls_assert-example-5-using-the-bsls-assertfailurehandlerguard}
963///
964///
965/// Sometimes we may want to replace, temporarily (i.e., within some local
966/// lexical scope), the currently installed assertion-failure handler function.
967/// In particular, we sometimes use the `bsls::AssertFailureHandlerGuard` class
968/// to replace the current handler with one that throws an exception (because we
969/// know that such an exception is safe in the local context). Let's start with
970/// the simple factorial function below, which validates, in "debug mode" (or
971/// "safe mode"), that its input is non-negative:
972/// @code
973/// /// Return `n!`. The behavior is undefined unless `0 <= n`.
974/// double fact(int n)
975/// {
976/// BSLS_ASSERT(0 <= n);
977///
978/// double result = 1.0;
979/// while (n > 1) {
980/// result *= n--;
981/// }
982/// return result;
983/// }
984/// @endcode
985/// Now consider the following integer-valued `extern "C"` C++ function,
986/// `wrapperFunc`, which can be called from C and FORTRAN, as well as from C++:
987/// @code
988/// extern "C" int wrapperFunc(bool verboseFlag)
989/// {
990/// enum { GOOD = 0, BAD } result = GOOD; (void) verboseFlag;
991/// @endcode
992/// The purpose of this function is to allow assertion failures in subroutine
993/// calls below this function to be handled by throwing an exception, which is
994/// then caught by the wrapper and reported to the caller as a "bad" status.
995/// Hence, when within the runtime scope of this function, we want to install,
996/// temporarily, the assertion-failure handler `bsls::Assert::failByThrow`,
997/// which, when invoked, causes an `bsls::AssertTestException` object to be
998/// thrown. (Note that we are not advocating this approach for "recovery", but
999/// rather for an orderly shut-down, or perhaps during testing.) The
1000/// `bsls::AssertFailureHandlerGuard` class is provided for just this purpose:
1001/// @code
1002/// assert(&bsls::Assert::failByAbort == bsls::Assert::violationHandler());
1003///
1004/// bsls::AssertFailureHandlerGuard guard(&bsls::Assert::failByThrow);
1005///
1006/// assert(&bsls::Assert::failByThrow == bsls::Assert::violationHandler());
1007/// @endcode
1008/// Next we open up a `try` block, and somewhere within the `try` we
1009/// "accidentally" invoke `fact` with an out-of-contract value (i.e., `-1`):
1010/// @code
1011/// #ifdef BDE_BUILD_TARGET_EXC
1012/// try
1013/// #endif
1014/// {
1015///
1016/// // ...
1017///
1018/// double d = fact(-1); // Out-of-contract call to 'fact'.
1019///
1020/// // ...
1021/// }
1022/// #ifdef BDE_BUILD_TARGET_EXC
1023/// catch (const bsls::AssertTestException& e) {
1024/// result = BAD;
1025/// if (verboseFlag) {
1026/// std::printf( "Internal Error: %s, %s, %d\n",
1027/// e.expression(),
1028/// e.filename(),
1029/// e.lineNumber() );
1030/// }
1031/// }
1032/// #endif
1033/// return result;
1034/// }
1035/// @endcode
1036/// Assuming exceptions are enabled (i.e., `BDE_BUILD_TARGET_EXC` is defined),
1037/// if an `bsls::AssertTestException` occurs below this wrapper function, the
1038/// exception will be caught, a message will be printed to `stdout`, e.g.,
1039/// @code
1040/// Internal Error: bsls_assert.t.cpp:500: 0 <= n
1041/// @endcode
1042/// and the `wrapperFunc` function will return a bad status (i.e., 1) to its
1043/// caller. Note that if exceptions are not enabled,
1044/// `bsls::Assert::failByThrow` will behave as `bsls::Assert::failByAbort`, and
1045/// dump core immediately:
1046/// @code
1047/// Assertion failed: 0 <= n, file bsls_assert.t.cpp, line 500
1048/// Abort (core dumped)
1049/// @endcode
1050/// Finally note that the `bsls::AssertFailureHandlerGuard` is not thread-aware.
1051/// In particular, a guard that is created in one thread will also affect the
1052/// failure handlers that are used in other threads. Care should be taken when
1053/// using this guard when more than a single thread is executing.
1054///
1055/// ### Example 6: Using (BSLS) "ASSERT" Macros Along With BDE_BUILD_TARGET_SAFE_2 {#bsls_assert-example-6-using-assert-macros-along-with-bde_build_target_safe_2}
1056///
1057///
1058/// Recall that assertions do not affect binary compatibility; however, software
1059/// built with `BDE_BUILD_TARGET_SAFE_2` defined need not be binary compatible
1060/// with software built otherwise. In this example, we look at how we might use
1061/// the (BSLS) "ASSERT" family of macros in conjunction with code that is
1062/// incorporated (at compile time) only when `BDE_BUILD_TARGET_SAFE_2` is
1063/// defined.
1064///
1065/// As a simple example, let's consider an elided implementation of a
1066/// singly-linked integer list and its iterator. Whenever
1067/// `BDE_BUILD_TARGET_SAFE_2` is defined, we want to defend against the
1068/// possibility that a client mistakenly passes a `ListIter` object into a
1069/// `List` object method (e.g., `List::insert`) where that `ListIter` object did
1070/// not originate from the same `List` object.
1071///
1072/// We'll start by defining a local helper `List_Link` `struct` as follows:
1073/// @code
1074/// struct List_Link {
1075/// List_Link *d_next_p;
1076/// int d_data;
1077/// List_Link(List_Link *next, int data) : d_next_p(next), d_data(data) { }
1078/// };
1079/// @endcode
1080/// Next, we'll define `ListIter`, which always identifies the current position
1081/// in a sequence of links, but whenever `BDE_BUILD_TARGET_SAFE_2` is defined,
1082/// also maintains a pointer to its parent `List` object:
1083/// @code
1084/// class List; // Forward declaration.
1085///
1086/// class ListIter {
1087/// #ifdef BDE_BUILD_TARGET_SAFE_2
1088/// List *d_parent_p; // Exists only in "safe 2 mode".
1089/// #endif
1090/// List_Link **d_current_p;
1091/// friend class List;
1092/// friend bool operator==(const ListIter&, const ListIter&);
1093/// private:
1094/// ListIter(List_Link **current,
1095/// List *
1096/// #ifdef BDE_BUILD_TARGET_SAFE_2
1097/// parent // Not used unless in "safe 2 mode".
1098/// #endif
1099/// )
1100/// : d_current_p(current)
1101/// #ifdef BDE_BUILD_TARGET_SAFE_2
1102/// , d_parent_p(parent) // Initialize only in "safe 2 mode".
1103/// #endif
1104/// { }
1105/// public:
1106/// ListIter& operator++() { /* ... */ return *this; }
1107/// // ...
1108/// };
1109/// bool operator==(const ListIter& lhs, const ListIter& rhs);
1110/// bool operator!=(const ListIter& lhs, const ListIter& rhs);
1111/// @endcode
1112/// Finally we define the `List` class itself with most of the operations
1113/// elided; the methods of particular interest here are `begin` and `insert`:
1114/// @code
1115///
1116/// class List {
1117/// List_Link *d_head_p;
1118/// public:
1119/// // CREATORS
1120/// List() : d_head_p(0) { }
1121/// List(const List&) { /* ... */ }
1122/// ~List() { /* ... */ }
1123///
1124/// // MANIPULATORS
1125/// List& operator=(const List&) { /* ... */ return *this; }
1126///
1127/// //| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
1128/// //v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v
1129/// //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1130///
1131/// /// Return an iterator referring to the beginning of this list.
1132/// ListIter begin()
1133/// {
1134/// return ListIter(&d_head_p, this);
1135/// }
1136/// //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1137///
1138/// //| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
1139/// //v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v
1140/// //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1141///
1142/// /// Insert the specified `data` value into this list at the specified
1143/// /// `position`.
1144/// void insert(const ListIter& position, int data)
1145/// {
1146/// #ifdef BDE_BUILD_TARGET_SAFE_2
1147/// BSLS_ASSERT_SAFE(this == position.d_parent_p); // "safe 2 mode"
1148/// #endif
1149/// *position.d_current_p = new List_Link(*position.d_current_p, data);
1150/// }
1151/// //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1152///
1153/// // ACCESSORS
1154///
1155/// /// Output the contents of this list to `stdout`.
1156/// void print()
1157/// {
1158/// printf( "[" );
1159/// for (List_Link *p = d_head_p; p; p = p->d_next_p) {
1160/// printf( " %d", p->d_data );
1161/// }
1162/// printf(" ]\n");
1163/// }
1164/// };
1165/// @endcode
1166/// Outside of "safe 2 mode", it is possible to pass an iterator object obtained
1167/// from the `begin` method of one `List` object into the `insert` method of
1168/// another, having, perhaps, unexpected results:
1169/// @code
1170/// void sillyFunc(bool printFlag)
1171/// {
1172/// List a;
1173/// ListIter aIt = a.begin();
1174/// a.insert(aIt, 1);
1175/// a.insert(aIt, 2);
1176/// a.insert(aIt, 3);
1177///
1178/// if (printFlag) {
1179/// std::printf( "a = "); a.print();
1180/// }
1181///
1182/// List b;
1183/// ListIter bIt = b.begin();
1184/// a.insert(bIt, 4); // Oops! Should have been: 'b.insert(bIt, 4);'
1185/// a.insert(bIt, 5); // Oops! " " " ' " " 5 '
1186/// a.insert(bIt, 6); // Oops! " " " ' " " 6 '
1187///
1188/// if (printFlag) {
1189/// std::printf( "a = "); a.print();
1190/// std::printf( "b = "); b.print();
1191/// }
1192/// }
1193/// @endcode
1194/// In the example above, we have "accidentally" passed the iterator `bIt`
1195/// obtained from `List` object `b` into the `insert` method for `List` object
1196/// `a`. The resulting undefined behavior (in other than "safe 2 mode") might
1197/// produce output that looks as follows:
1198/// @code
1199/// a = [ 3 2 1 ]
1200/// a = [ 3 2 1 ]
1201/// b = [ 6 5 4 ]
1202/// @endcode
1203/// If the same `sillyFunc` were compiled in "safe 2 mode" (i.e., with
1204/// `BDE_BUILD_TARGET_SAFE_2` defined) the undefined behavior would be detected
1205/// and the output would, by default, look more like the following:
1206/// @code
1207/// a = [ 3 2 1 ]
1208/// FATAL my_list.cpp:56 Assertion failed: this == position.d_parent_p
1209/// Abort (core dumped)
1210/// @endcode
1211/// thereby quickly exposing the misuse by the client.
1212///
1213/// ### Example 7: Conditional Compilation Associated with Enabled Assertion Levels {#bsls_assert-example-7-conditional-compilation-associated-with-enabled-assertion-levels}
1214///
1215///
1216/// In cases where we want to tie code, other than just an assertion, to a
1217/// specific level of enabled assertions, we will want to use the corresponding
1218/// intermediate predicate that enables that level of assertions:
1219///
1220/// * For `BSLS_ASSERT_SAFE`, use `BSLS_ASSERT_SAFE_IS_ACTIVE`.
1221/// * For `BSLS_ASSERT`, use `BSLS_ASSERT_IS_ACTIVE`.
1222/// * For `BSLS_ASSERT_OPT`, use `BSLS_ASSERT_OPT_IS_ACTIVE`.
1223///
1224/// Suppose that we have a class such as `MyDate` (below) that, except for
1225/// checking its invariants, would have a trivial destructor. By not declaring
1226/// a destructor at all, we may realize performance advantages, but then we lose
1227/// the ability to validate our invariants in "debug" or "safe" mode. What we
1228/// want to do is to declare (and later define) the destructor in precisely
1229/// those build modes for which we would want to assert invariants.
1230///
1231/// An elided class `MyDate`, which is based on a serial-date implementation, is
1232/// provided for reference:
1233/// @code
1234/// /// This class implements a value-semantic "date" type representing
1235/// /// valid date values in the range `[ 0001Jan01 .. 9999Dec31 ]`.
1236/// class MyDate {
1237///
1238/// // DATA
1239/// int d_serialDate; // sequential representation within a valid range
1240///
1241/// public:
1242/// // CLASS METHODS
1243///
1244/// // ...
1245///
1246/// // CREATORS
1247///
1248/// /// Create a `MyDate` object having the value `0001Jan01`.
1249/// MyDate();
1250///
1251/// // ...
1252///
1253/// /// Create a `MyDate` object having the same value as the specified
1254/// /// `original` object.
1255/// MyDate(const MyDate& original);
1256///
1257/// #if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1258/// /// Destroy this object. Note that in some build modes the
1259/// /// destructor generated by the compiler is trivial.
1260/// ~MyDate();
1261/// #endif
1262///
1263/// // ...
1264/// };
1265///
1266/// ...
1267///
1268/// ========================================================================
1269/// INLINE FUNCTION DEFINITIONS
1270/// ========================================================================
1271///
1272/// ...
1273///
1274/// CREATORS
1275/// inline
1276/// MyDate::MyDate()
1277/// : d_serialDate(1) // 0001Jan01
1278/// {
1279/// }
1280///
1281/// inline
1282/// MyDate::MyDate(const MyDate& original)
1283/// : d_serialDate(original.d_serialDate)
1284/// {
1285/// }
1286///
1287/// ...
1288///
1289/// #if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1290/// inline
1291/// MyDate::~MyDate()
1292/// {
1293/// BSLS_ASSERT_SAFE(1 <= d_serialDate); // 0001Jan01
1294/// BSLS_ASSERT_SAFE( d_serialDate <= 3652061); // 9999Dec31
1295/// }
1296/// #endif
1297///
1298/// ...
1299/// @endcode
1300/// In practice, however, we would probably implement an `isValidSerialDate`
1301/// method in a lower-level utility class, e.g., `MyDateImpUtil`, leading to
1302/// code that is more fine-grained, modular, and hierarchically reusable:
1303/// @code
1304/// struct MyDateImpUtil {
1305/// /// Return `true` if the specified `d_date` represents a valid date
1306/// /// value, and `false` otherwise.
1307/// static bool isValidSerialDate(int d_date);
1308/// };
1309///
1310/// inline
1311/// bool MyDateImpUtil::isValidSerialDate(int d_date)
1312/// {
1313/// return 1 <= d_date && d_date <= 3652061;
1314/// }
1315/// @endcode
1316/// Like other aspects of `BSLS_ASSERT_SAFE`, the example above violates the
1317/// one-definition rule for mixed-mode builds. Note that all code conditionally
1318/// compiled based on `BSLS_ASSERT_SAFE_IS_ACTIVE`, `BSLS_ASSERT_IS_ACTIVE`, and
1319/// `BSLS_ASSERT_OPT_IS_ACTIVE` should be binary compatible for mixed-mode
1320/// builds. If the conditionally-compiled code would not be binary compatible,
1321/// use `BDE_BUILD_TARGET_SAFE_2` instead.
1322///
1323/// WARNING - In practice, declaring a destructor in some build modes but not
1324/// others has led to subtle and difficult-to-diagnose failures. DON'T DO IT!
1325///
1326/// Finally, in very rare cases, we may want to put in (redundant) defensive
1327/// code (in the spirit of `BSLS_ASSERT_OPT`) that is not part of the
1328/// component-level contract, yet (1) is known to have negligible runtime cost
1329/// and (2) is deemed to be so important as to be necessary even for optimized
1330/// builds.
1331///
1332/// For example, consider again the `MyDate` class above that now also declares
1333/// a non-`inline` `print` method to format the current date value in some
1334/// human-readable, but otherwise unspecified format:
1335/// @code
1336/// xyza_mydate.h
1337/// ...
1338/// class MyDate {
1339/// // ...
1340///
1341/// // DATA
1342/// int d_serialDate; // sequential representation within a valid range
1343///
1344/// public:
1345/// // ...
1346/// // ACCESSORS
1347/// // ...
1348///
1349/// /// Write the value of this object to the specified output `stream`
1350/// /// in some human-readable format, and return a reference to
1351/// /// `stream`. Optionally specify ...
1352/// std::ostream& print(std::ostream& stream, ...) const;
1353///
1354/// // ...
1355///
1356/// };
1357/// @endcode
1358/// Successfully writing bad data is among the most insidious of bugs, because a
1359/// latent error can persist and not be discovered until long after the program
1360/// terminates. Writing the value of a corrupted `MyDate` object in a
1361/// **machine-readable** (binary) format is an error so serious as to warrant
1362/// invoking
1363/// @code
1364/// void testFunction(int d_serialDate) {
1365/// BSLS_ASSERT_OPT(MyDateImpUtil::isValidSerialDate(d_serialDate));
1366/// }
1367/// @endcode
1368/// each time we attempt the output operation; however, printing the value in a
1369/// human-readable format intended primarily for debugging purposes is another
1370/// matter. In anything other than a safe build (which in this case would
1371/// enforce essentially all method preconditions), it would be unfortunate if a
1372/// developer, knowing that there was a problem involving the use of `MyDate`,
1373/// inserted print statements to identify that problem, only to have the `print`
1374/// method itself ruthlessly invoke the assert handler, likely terminating the
1375/// process). Moreover, it may also be unsafe even to attempt to format the
1376/// value of a `MyDate` object whose `d_serialDate` value violates its
1377/// invariants (e.g., due to a static table lookup). In such cases we may, as
1378/// sympathetic library developers, choose to implement different undefined
1379/// (undocumented) redundant defensive behaviors, depending on the desired level
1380/// of assertions:
1381/// @code
1382/// xyza_mydate.cpp
1383/// ...
1384/// #include <xyza_mydateimputil.h>
1385/// ...
1386///
1387/// std::ostream& MyDate::print(std::ostream& stream, ...) const
1388/// {
1389/// // BSLS_ASSERT(/* any *argument* preconditions for this function */);
1390///
1391/// // Handle case where the invariants have been violated.
1392///
1393/// #ifdef BSLS_ASSERT_OPT_IS_ACTIVE
1394/// // Note that if 'BSLS_ASSERT_LEVEL_NONE' has been set, this code --
1395/// // along with all 'BSLS_ASSERT_OPT' macros -- will not instantiate,
1396/// // enabling us to verify that the combined runtime overhead of all such
1397/// // (redundant) defensive code is at worst negligible, if not
1398/// // unmeasurable.
1399///
1400/// if (!MyDateImpUtil::isValidSerialDate(d_serialDate)) {
1401///
1402/// // Our invariant is corrupted.
1403///
1404/// #ifdef BSLS_ASSERT_IS_ACTIVE
1405/// // Providing debugging information in this mode would be useful.
1406///
1407/// std::cerr << "\nxyza::MyDate: Invalid internal serial date value "
1408/// << d_serialDate << '.' << std::endl;
1409///
1410/// #endif // BSLS_ASSERT_IS_ACTIVE
1411///
1412/// // In safe mode, each of the 'MyClass' methods fully guards its
1413/// // preconditions: There is simply no easy way to get here!
1414///
1415/// BSLS_ASSERT_SAFE("Probable rogue memory overwrite!" && 0);
1416///
1417/// // If we get here, we're corrupted, but not in safe mode!
1418///
1419/// return stream << "(* Invalid 'MyDate' State "
1420/// << d_serialDate
1421/// << " *)" << std::flush; // RETURN
1422///
1423/// }
1424/// #endif // BSLS_ASSERT_OPT_IS_ACTIVE
1425///
1426/// // If we get here in a production build, this object is "sane": Do
1427/// // whatever this 'print' method would normally do, assuming that no
1428/// // method preconditions or object invariants are violated.
1429///
1430/// // ... <*** Your (Normal-Case) Formatting Code Here! ***>
1431///
1432/// return stream;
1433/// }
1434/// @endcode
1435/// ### Example 8: Conditional Compilation of Support Functions {#bsls_assert-example-8-conditional-compilation-of-support-functions}
1436///
1437///
1438/// Occasionally a function may exist only to support a specific set of
1439/// assertions. Often this can happen when a large expression that captures a
1440/// complicated precondition wants to be refactored into a distinct location to
1441/// ease understanding of it. When this happens the function might still remain
1442/// as a private implementation detail of the class.
1443///
1444/// When the only assertion macros that use the function are disabled this can
1445/// lead to a compiler warning about a function being unused, and the
1446/// corresponding code bloat from having the function available might be an
1447/// overhead that is not desired.
1448///
1449/// In order to totally remove the function when it is not needed, the `IS_USED`
1450/// suffixed macros can be used to guard the declaration and definition of the
1451/// function. Suppose we have a `class` with a function having a complex
1452/// precondition, and that precondition check is both private and only needed
1453/// when the assertions that use it are enabled. In that case, we can guard the
1454/// definitions and declarations against even being compiled like this:
1455/// @code
1456/// class ComplexObject {
1457/// // ...
1458/// #if defined(BSLS_ASSERT_SAFE_IS_USED)
1459/// /// Return `true` if the current state of this object fits within the
1460/// /// complex requirements of being sufficiently purple, false otherwise.
1461/// bool isPurplish() const;
1462/// #endif
1463/// // ...
1464/// public:
1465/// // MANIPULATORS
1466///
1467/// /// Do something purpley. The behavior is undefined unless this object
1468/// /// is currently purplish (contact customer support to know the current
1469/// /// threshholds for purplishness).
1470/// void doSomethingPurpley();
1471/// };
1472///
1473/// #if defined(BSLS_ASSERT_SAFE_IS_USED)
1474/// bool ComplexObject::isPurplish() const
1475/// {
1476/// // The real implementation would encode the complex logic of needing to
1477/// // determine if this object feels purplish at the moment.
1478/// return true;
1479/// }
1480/// #endif
1481///
1482/// void ComplexObject::doSomethingPurpley()
1483/// {
1484/// BSLS_ASSERT_SAFE(isPurplish());
1485/// }
1486/// @endcode
1487/// Now, the `ComplexObject::isPurplish` function will only exist in a subset of
1488/// builds:
1489/// * When `BSLS_ASSERT_SAFE` assertions are enabled in assert or review mode,
1490/// the function will be compiled and invoked.
1491/// * When `BSLS_ASSERT_VALIDATE_DISABLED_MACROS` is defined the function will
1492/// be compiled. This will make sure that a future change does not
1493/// invalidate the implementation of `isPurplish()` even though it is not
1494/// used.
1495/// * When `BSLS_ASSERT_SAFE` assertions are assumed the function will be
1496/// compiled and might be invoked, or at least have its implementation
1497/// inspected by the compiler to improve code generation.
1498///
1499/// ### Example 9: Conditional Compilation of Support Code {#bsls_assert-example-9-conditional-compilation-of-support-code}
1500///
1501///
1502/// Sometimes there is code that needs to run in a function before an assertion
1503/// to gather information needed only by that assertion. Often this can be
1504/// capturing input values or other system state before it is modified and
1505/// verifying at the end of a function that the values are changed (or not)
1506/// appropriately.
1507///
1508/// When the corresponding assertion macro is not active in assert or review
1509/// mode the supporting code should not be executed at all. Importantly,
1510/// because the capturing of additional information is an extra cost, the
1511/// assertion itself does not lend itself to being assumed.
1512///
1513/// Suppose we have a function that wishes to swap the values of its input:
1514/// @code
1515/// struct MySwapper {
1516///
1517/// /// Exchange the values of the specified `lhs` and `rhs`.
1518/// template <class T>
1519/// static void swap(T& lhs, T& rhs)
1520/// {
1521/// T tmp = lhs;
1522/// lhs = rhs;
1523/// rhs = tmp;
1524/// }
1525/// };
1526/// @endcode
1527/// This works great as a simple `swap` implementation, but we would like to
1528/// assert in safe mode that it is doing the correct thing. In order to do that
1529/// we need to capture the initial values of our inputs before doing anything
1530/// else, and we want to do this only when the respective assertions are
1531/// enabled. Here we would guard our code and our assertions in a check that
1532/// `BSLS_ASSERT_SAFE_IS_ACTIVE` is defined, like this:
1533/// @code
1534/// struct MySwapper {
1535///
1536/// /// Exchange the values of the specified `lhs` and `rhs`.
1537/// template <class T>
1538/// static void swap(T& lhs, T& rhs)
1539/// {
1540/// #if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1541/// T origLhs(lhs);
1542/// T origRhs(rhs);
1543/// #endif
1544/// T tmp = lhs;
1545/// lhs = rhs;
1546/// rhs = tmp;
1547/// #if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1548/// BSLS_ASSERT_SAFE(rhs == origLhs);
1549/// BSLS_ASSERT_SAFE(lhs == origRhs);
1550/// #endif
1551/// }
1552/// };
1553/// @endcode
1554///
1555/// ### Example 10: Asserting a Branch Is Unreachable {#bsls_assert-example-10-asserting-a-branch-is-unreachable}
1556///
1557///
1558/// Sometimes a developer knows that it would always be a bug for a particular
1559/// branch to be taken. For example, when handling a set of values in an
1560/// exhaustive `switch` statement, the default branch "should not" be taken
1561/// because the set of values is known to be limited at the point of the
1562/// `switch` (but a wrong value can be created by a bug, or perhaps by a future
1563/// change to the `enum`).
1564///
1565/// There may be several situations depending on the code in question and its
1566/// state. In existing code one may have an unconditional BSLS_ASSERT_OPT that
1567/// is already being used to "cover" the unreachable branch:
1568/// @code
1569/// enum Action { e_CLEAR, e_SET, e_TOGGLE };
1570///
1571/// void badExistingDoAction(Action value) {
1572/// switch (value) {
1573/// case e_CLEAR: doClear(); break;
1574/// case e_SET: doSet(); break;
1575/// case e_TOGGLE: doToggle(); break;
1576/// default: BSLS_ASSERT_OPT(false); break;
1577/// }
1578/// }
1579/// @endcode
1580/// `BSLS_ASSERT_OPT` is of course not ideal for this purpose because it has a
1581/// condition that we need to set to `false` and there is no convenient place to
1582/// put a message that describes what the issue is. Using the dedicated
1583/// unreachable macro instead is much more clear and allows for a message to be
1584/// included that describes the issue, like this:
1585/// @code
1586/// void updatedDoAction(Action value) {
1587/// switch (value) {
1588/// case e_CLEAR: doClear(); break;
1589/// case e_SET: doSet(); break;
1590/// case e_TOGGLE: doToggle(); break;
1591/// default: BSLS_ASSERT_OPT_UNREACHABLE("Unknown Action"); break;
1592/// }
1593/// }
1594/// @endcode
1595/// Using `BSLS_ASSERT_OPT_UNREACHABLE` allows us to keep the configurability of
1596/// the original assertion, while making it much more clear that the branch is
1597/// not expected to be taken and providing a message that describes the issue if
1598/// it is taken. Moreover, if we wanted to introduce this assertion at the
1599/// REVIEW level, we could do so by changing the macro used in the `default`
1600/// case to `BSLS_ASSERT_REVIEW_UNREACHABLE`.
1601///
1602/// Say we are writing a `doAction` method the first time and the action is so
1603/// critical that we want to make sure that the default branch is never taken,
1604/// therefore we do not want the assertion to be configurable. Instead want it
1605/// to be an unconditional assertion that always fires when the branch is taken.
1606/// In that case, we may use `BSLS_ASSERT_INVOKE_NORETURN` instead:
1607/// @code
1608/// void newlyWrittenDoAction(Action value) {
1609/// switch (value) {
1610/// case e_CLEAR: doClear(); break;
1611/// case e_SET: doSet(); break;
1612/// case e_TOGGLE: doToggle(); break;
1613/// default: BSLS_ASSERT_INVOKE_NORETURN("Unknown Action");
1614/// }
1615/// }
1616/// @endcode
1617/// It is important to note that the `BSLS_ASSERT_INVOKE_NORETURN` macro does
1618/// not provide any way to disable the assertion, so it should be used only when
1619/// the branch is truly expected to be unreachable. If the method is frequently
1620/// called with an unknown action it will keep bringing the system down.
1621///
1622/// There may also be a case when we do not want any assertion to be invoked,
1623/// because the method itself is not critical at all, more informational. For
1624/// example while a `toAscii` method for an `enum` is very useful for debugging,
1625/// we really do not want the act of formatting an error log message (with a
1626/// bad `enum` value) to cause the system to crash. In such case we rely on the
1627/// fact that this is an information function and simply return a string that
1628/// indicates the value is unknown, without invoking any kind of assertion:
1629/// @code
1630/// enum Color { e_RED, e_GREEN, e_BLUE };
1631///
1632/// const char *toAscii(Color value) {
1633/// switch (value) {
1634/// case e_RED: return "RED";
1635/// case e_GREEN: return "GREEN";
1636/// case e_BLUE: return "BLUE";
1637/// }
1638/// return "(* UNKNOWN COLOR *)";
1639/// }
1640/// @endcode
1641/// As the examples show library designers should employ careful consideration
1642/// when deciding which type of assertion to use to ensure system stability,
1643/// security, observability, and build artifact configurability. When in doubt,
1644/// err on the side of giving the owner of `main` more control over the behavior
1645/// of the system, or avoid the possibility of bringing the system down if that
1646/// action won't hide an error.
1647/// @}
1648/** @} */
1649/** @} */
1650
1651/** @addtogroup bsl
1652 * @{
1653 */
1654/** @addtogroup bsls
1655 * @{
1656 */
1657/** @addtogroup bsls_assert
1658 * @{
1659 */
1660
1661#include <bsls_annotation.h>
1662#include <bsls_assertimputil.h>
1663#include <bsls_buildtarget.h>
1664#include <bsls_compilerfeatures.h>
1665#include <bsls_keyword.h>
1666#include <bsls_performancehint.h>
1667#include <bsls_platform.h>
1668#include <bsls_review.h>
1669
1670#ifdef BSLS_ASSERT_USE_CONTRACTS
1671#include <contract>
1672#endif
1673
1674 // =============================
1675 // Checks for Pre-Defined macros
1676 // =============================
1677
1678#if defined(BSLS_ASSERT_OPT)
1679#error BSLS_ASSERT_OPT is already defined!
1680#endif
1681
1682#if defined(BSLS_ASSERT_OPT_IS_ACTIVE)
1683#error BSLS_ASSERT_OPT_IS_ACTIVE is already defined!
1684#endif
1685
1686#if defined(BSLS_ASSERT_OPT_IS_ASSUMED)
1687#error BSLS_ASSERT_OPT_IS_ASSUMED is already defined!
1688#endif
1689
1690#if defined(BSLS_ASSERT_OPT_IS_REVIEW)
1691#error BSLS_ASSERT_OPT_IS_REVIEW is already defined!
1692#endif
1693
1694#if defined(BSLS_ASSERT_OPT_IS_USED)
1695#error BSLS_ASSERT_OPT_IS_USED is already defined!
1696#endif
1697
1698#if defined(BSLS_ASSERT)
1699#error BSLS_ASSERT is already defined!
1700#endif
1701
1702#if defined(BSLS_ASSERT_IS_ACTIVE)
1703#error BSLS_ASSERT_IS_ACTIVE is already defined!
1704#endif
1705
1706#if defined(BSLS_ASSERT_IS_ASSUMED)
1707#error BSLS_ASSERT_IS_ASSUMED is already defined!
1708#endif
1709
1710#if defined(BSLS_ASSERT_IS_REVIEW)
1711#error BSLS_ASSERT_IS_REVIEW is already defined!
1712#endif
1713
1714#if defined(BSLS_ASSERT_IS_USED)
1715#error BSLS_ASSERT_IS_USED is already defined!
1716#endif
1717
1718#if defined(BSLS_ASSERT_SAFE)
1719#error BSLS_ASSERT_SAFE is already defined!
1720#endif
1721
1722#if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1723#error BSLS_ASSERT_SAFE_IS_ACTIVE is already defined!
1724#endif
1725
1726#if defined(BSLS_ASSERT_SAFE_IS_ASSUMED)
1727#error BSLS_ASSERT_SAFE_IS_ASSUMED is already defined!
1728#endif
1729
1730#if defined(BSLS_ASSERT_SAFE_IS_REVIEW)
1731#error BSLS_ASSERT_SAFE_IS_REVIEW is already defined!
1732#endif
1733
1734#if defined(BSLS_ASSERT_SAFE_IS_USED)
1735#error BSLS_ASSERT_SAFE_IS_USED is already defined!
1736#endif
1737
1738#if defined(BSLS_ASSERT_INVOKE)
1739#error BSLS_ASSERT_INVOKE is already defined!
1740#endif
1741
1742#if defined(BSLS_ASSERT_INVOKE_NORETURN)
1743#error BSLS_ASSERT_INVOKE_NORETURN is already defined!
1744#endif
1745
1746#if defined(BSLS_ASSERT_SAFE_UNREACHABLE)
1747#error BSLS_ASSERT_SAFE_UNREACHABLE is already defined!
1748#endif
1749
1750#if defined(BSLS_ASSERT_UNREACHABLE)
1751#error BSLS_ASSERT_UNREACHABLE is already defined!
1752#endif
1753
1754#if defined(BSLS_ASSERT_OPT_UNREACHABLE)
1755#error BSLS_ASSERT_OPT_UNREACHABLE is already defined!
1756#endif
1757
1758 // =================================
1759 // (BSLS) "ASSERT" Macro Definitions
1760 // =================================
1761
1762// Implementation Note: We wrap the 'if' statement below in a (seemingly
1763// redundant) do-while-false loop to require, syntactically, a trailing
1764// semicolon, and to ensure that the macro behaves properly in an if-then-else
1765// context -- even if one forgets to wrap, with curly braces, the body of an
1766// 'if' having just a single 'BSLS_ASSERT*' statement.
1767
1768 // =============================================
1769 // Factored Implementation for Internal Use Only
1770 // =============================================
1771
1772#if !(defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) || \
1773 defined(BSLS_ASSERT_LEVEL_ASSERT) || \
1774 defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) || \
1775 defined(BSLS_ASSERT_LEVEL_NONE) || \
1776 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT) || \
1777 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT) || \
1778 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE))
1779 #define BSLS_ASSERT_NO_ASSERTION_MACROS_DEFINED 1
1780#else
1781 #define BSLS_ASSERT_NO_ASSERTION_MACROS_DEFINED 0
1782#endif
1783
1784#ifdef BSLS_ASSERT_USE_CONTRACTS
1785#define BSLS_ASSERT_ASSERT_IMP(X,LVL) [[ assert check_never_continue : X ]]
1786
1787#define BSLS_ASSERT_ASSUME_IMP(X,LVL) [[ assert assume : X ]]
1788#define BSLS_ASSERT_ASSUME_ENABLED
1789
1790#ifdef BSLS_ASSERT_VALIDATE_DISABLED_MACROS
1791#define BSLS_ASSERT_DISABLED_IMP(X,LVL) [[ assert ignore : X ]]
1792#else
1793#define BSLS_ASSERT_DISABLED_IMP(X,LVL) [[ assert : true ]]
1794#endif
1795
1796#else
1797#define BSLS_ASSERT_ASSERT_IMP(X,LVL) do { \
1798 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!(X))) { \
1799 BSLS_PERFORMANCEHINT_UNLIKELY_HINT; \
1800 BloombergLP::bsls::Assert::invokeHandler( \
1801 BloombergLP::bsls::AssertViolation(#X, \
1802 BSLS_ASSERTIMPUTIL_FILE, \
1803 BSLS_ASSERTIMPUTIL_LINE, \
1804 LVL)); \
1805 } \
1806 } while (false)
1807
1808#if defined(BSLS_PLATFORM_CMP_CLANG)
1809
1810#define BSLS_ASSERT_ASSUME_IMP(X,LVL) __builtin_assume((X)?true:false)
1811#define BSLS_ASSERT_ASSUME_ENABLED
1812
1813#elif defined(BSLS_PLATFORM_CMP_GNU)
1814// While a common practice with GCC is to implement assumptions using an
1815// expression of the form 'if (!(X)) __builtin_unreachable();', this idiom
1816// relies on the expression 'X' being inline and truly sideeffect free before
1817// GCC will consistently elide the check itself, making this a pessimisation
1818// when used arbitrarily. Because of this we do not attempt to leverage
1819// assumption on GCC and leave the following commented out:
1820//..
1821// #define BSLS_ASSERT_ASSUME_IMP(X,LVL) if (!(X)) { __builtin_unreachable(); }
1822// #define BSLS_ASSERT_ASSUME_ENABLED
1823//..
1824
1825#elif defined (BSLS_PLATFORM_CMP_MSVC)
1826#define BSLS_ASSERT_ASSUME_IMP(X,LVL) __assume((X)?true:false)
1827#define BSLS_ASSERT_ASSUME_ENABLED
1828
1829#endif
1830
1831#if !defined(BSLS_ASSERT_ASSUME_IMP)
1832// The above flavors of 'assumption' are the only available ones that we
1833// support, and the only platforms where we currently attempt to use
1834// assumption.
1835#define BSLS_ASSERT_ASSUME_IMP(X,LVL) BSLS_ASSERT_DISABLED_IMP(X,LVL)
1836#endif
1837
1838#ifdef BSLS_ASSERT_VALIDATE_DISABLED_MACROS
1839#define BSLS_ASSERT_DISABLED_IMP(X,LVL) do { \
1840 static_cast<void>(sizeof((!(X))?true:false)); \
1841 } while (false)
1842#else
1843#define BSLS_ASSERT_DISABLED_IMP(X,LVL) do {} while (false)
1844#endif
1845#endif
1846
1847 // =====================================================
1848 // UNREACHABLE Factored Implementation for Internal Use
1849 // =====================================================
1850
1851// 'BSLS_ASSERT_UNREACHABLE_IMP' invokes the assertion handler unconditionally
1852// with the specified message 'X'. Unlike 'BSLS_ASSERT_ASSERT_IMP', this macro
1853// does not check a condition --- it always invokes the handler when reached.
1854
1855#define BSLS_ASSERT_UNREACHABLE_IMP(X,LVL) do { \
1856 BloombergLP::bsls::Assert::invokeHandler( \
1857 BloombergLP::bsls::AssertViolation( \
1858 X, \
1859 BSLS_ASSERTIMPUTIL_FILE, \
1860 BSLS_ASSERTIMPUTIL_LINE, \
1861 LVL)); \
1862 } while (false)
1863
1864// 'BSLS_ASSERT_UNREACHABLE_DISABLED_IMP' does nothing except ensures that `X`
1865// is a valid expression convertable to 'const char *'. It is used when the
1866// corresponding UNREACHABLE macro is disabled for the current build mode.
1867
1868#define BSLS_ASSERT_UNREACHABLE_DISABLED_IMP(X,LVL) do { \
1869 (void)sizeof(static_cast<const char*>(X)); \
1870} while (false)
1871
1872 // ================
1873 // BSLS_ASSERT_SAFE
1874 // ================
1875
1876// Determine if 'BSLS_ASSERT_SAFE' should be active.
1877
1878// Define the control macros, also usable from client code.
1879#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) \
1880 || BSLS_ASSERT_NO_ASSERTION_MACROS_DEFINED && ( \
1881 defined(BDE_BUILD_TARGET_SAFE_2) || \
1882 defined(BDE_BUILD_TARGET_SAFE) )
1883 #define BSLS_ASSERT_SAFE_IS_ACTIVE
1884#elif defined(BSLS_REVIEW_SAFE_IS_ACTIVE)
1885 #define BSLS_ASSERT_SAFE_IS_REVIEW
1886#elif defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE) && \
1887 !defined(BSLS_REVIEW_OPT_IS_ACTIVE) && \
1888 !defined(BSLS_REVIEW_IS_ACTIVE) && \
1889 !defined(BSLS_REVIEW_SAFE_IS_ACTIVE)
1890 #define BSLS_ASSERT_SAFE_IS_ASSUMED
1891#endif
1892
1893// Indicate when 'BSLS_ASSERT_SAFE' arguments will be ODR-used.
1894#if defined(BSLS_ASSERT_SAFE_IS_REVIEW) || \
1895 defined(BSLS_ASSERT_SAFE_IS_ACTIVE) || \
1896 (defined(BSLS_ASSERT_SAFE_IS_ASSUMED) \
1897 && defined(BSLS_ASSERT_ASSUME_ENABLED)) || \
1898 defined(BSLS_ASSERT_VALIDATE_DISABLED_MACROS)
1899 #define BSLS_ASSERT_SAFE_IS_USED
1900#endif
1901
1902// Define 'BSLS_ASSERT_SAFE' accordingly.
1903
1904#if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1905 #define BSLS_ASSERT_SAFE(X) BSLS_ASSERT_ASSERT_IMP( \
1906 X, \
1907 BloombergLP::bsls::Assert::k_LEVEL_SAFE)
1908#elif defined(BSLS_ASSERT_SAFE_IS_REVIEW)
1909 #define BSLS_ASSERT_SAFE(X) BSLS_REVIEW_REVIEW_IMP( \
1910 X, \
1911 BloombergLP::bsls::Assert::k_LEVEL_SAFE)
1912#elif defined(BSLS_ASSERT_SAFE_IS_ASSUMED)
1913 #define BSLS_ASSERT_SAFE(X) BSLS_ASSERT_ASSUME_IMP( \
1914 X, \
1915 BloombergLP::bsls::Assert::k_LEVEL_SAFE)
1916#else
1917 #define BSLS_ASSERT_SAFE(X) BSLS_ASSERT_DISABLED_IMP( \
1918 X, \
1919 BloombergLP::bsls::Assert::k_LEVEL_SAFE)
1920#endif
1921
1922// Define 'BSLS_ASSERT_SAFE_UNREACHABLE' accordingly.
1923
1924#if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1925 #define BSLS_ASSERT_SAFE_UNREACHABLE(X) BSLS_ASSERT_UNREACHABLE_IMP( \
1926 X, \
1927 BloombergLP::bsls::Assert::k_LEVEL_SAFE)
1928#elif defined(BSLS_ASSERT_SAFE_IS_REVIEW)
1929 #define BSLS_ASSERT_SAFE_UNREACHABLE(X) BSLS_REVIEW_UNREACHABLE_IMP( \
1930 X, \
1931 BloombergLP::bsls::Assert::k_LEVEL_SAFE)
1932#else
1933 #define BSLS_ASSERT_SAFE_UNREACHABLE(X) \
1934 BSLS_ASSERT_UNREACHABLE_DISABLED_IMP( \
1935 X, \
1936 BloombergLP::bsls::Assert::k_LEVEL_SAFE)
1937#endif
1938
1939
1940 // ===========
1941 // BSLS_ASSERT
1942 // ===========
1943
1944// Determine if 'BSLS_ASSERT' should be active.
1945
1946// Define the control macros, also usable from client code.
1947#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) || \
1948 defined(BSLS_ASSERT_LEVEL_ASSERT) \
1949 || BSLS_ASSERT_NO_ASSERTION_MACROS_DEFINED && ( \
1950 defined(BDE_BUILD_TARGET_SAFE_2) || \
1951 defined(BDE_BUILD_TARGET_SAFE) || \
1952 !defined(BDE_BUILD_TARGET_OPT) )
1953 #define BSLS_ASSERT_IS_ACTIVE
1954#elif defined(BSLS_REVIEW_IS_ACTIVE)
1955 #define BSLS_ASSERT_IS_REVIEW
1956#elif (defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE) || \
1957 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)) && \
1958 !defined(BSLS_REVIEW_OPT_IS_ACTIVE) && \
1959 !defined(BSLS_REVIEW_IS_ACTIVE) && \
1960 !defined(BSLS_REVIEW_SAFE_IS_ACTIVE)
1961 #define BSLS_ASSERT_IS_ASSUMED
1962#endif
1963
1964// Indicate when 'BSLS_ASSERT' arguments will be ODR-used.
1965#if defined(BSLS_ASSERT_IS_REVIEW) || \
1966 defined(BSLS_ASSERT_IS_ACTIVE) || \
1967 (defined(BSLS_ASSERT_IS_ASSUMED) \
1968 && defined(BSLS_ASSERT_ASSUME_ENABLED)) || \
1969 defined(BSLS_ASSERT_VALIDATE_DISABLED_MACROS)
1970 #define BSLS_ASSERT_IS_USED
1971#endif
1972
1973// Define 'BSLS_ASSERT' accordingly.
1974
1975#if defined(BSLS_ASSERT_IS_ACTIVE)
1976 #define BSLS_ASSERT(X) BSLS_ASSERT_ASSERT_IMP( \
1977 X, \
1978 BloombergLP::bsls::Assert::k_LEVEL_ASSERT)
1979#elif defined(BSLS_ASSERT_IS_REVIEW)
1980 #define BSLS_ASSERT(X) BSLS_REVIEW_REVIEW_IMP( \
1981 X, \
1982 BloombergLP::bsls::Assert::k_LEVEL_ASSERT)
1983#elif defined(BSLS_ASSERT_IS_ASSUMED)
1984 #define BSLS_ASSERT(X) BSLS_ASSERT_ASSUME_IMP( \
1985 X, \
1986 BloombergLP::bsls::Assert::k_LEVEL_ASSERT)
1987#else
1988 #define BSLS_ASSERT(X) BSLS_ASSERT_DISABLED_IMP( \
1989 X, \
1990 BloombergLP::bsls::Assert::k_LEVEL_ASSERT)
1991#endif
1992
1993// Define 'BSLS_ASSERT_UNREACHABLE' accordingly.
1994
1995#if defined(BSLS_ASSERT_IS_ACTIVE)
1996 #define BSLS_ASSERT_UNREACHABLE(X) BSLS_ASSERT_UNREACHABLE_IMP( \
1997 X, \
1998 BloombergLP::bsls::Assert::k_LEVEL_ASSERT)
1999#elif defined(BSLS_ASSERT_IS_REVIEW)
2000 #define BSLS_ASSERT_UNREACHABLE(X) BSLS_REVIEW_UNREACHABLE_IMP( \
2001 X, \
2002 BloombergLP::bsls::Assert::k_LEVEL_ASSERT)
2003#else
2004 #define BSLS_ASSERT_UNREACHABLE(X) \
2005 BSLS_ASSERT_UNREACHABLE_DISABLED_IMP( \
2006 X, \
2007 BloombergLP::bsls::Assert::k_LEVEL_ASSERT)
2008#endif
2009
2010 // ===============
2011 // BSLS_ASSERT_OPT
2012 // ===============
2013
2014// Determine if 'BSLS_ASSERT_OPT' should be active.
2015
2016// Define the control macros, also usable from client code.
2017#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) || \
2018 defined(BSLS_ASSERT_LEVEL_ASSERT) || \
2019 defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) \
2020 || BSLS_ASSERT_NO_ASSERTION_MACROS_DEFINED
2021 #define BSLS_ASSERT_OPT_IS_ACTIVE
2022#elif defined(BSLS_REVIEW_OPT_IS_ACTIVE)
2023 #define BSLS_ASSERT_OPT_IS_REVIEW
2024#elif (defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE) || \
2025 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT) || \
2026 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)) && \
2027 !defined(BSLS_REVIEW_OPT_IS_ACTIVE) && \
2028 !defined(BSLS_REVIEW_IS_ACTIVE) && \
2029 !defined(BSLS_REVIEW_SAFE_IS_ACTIVE)
2030 #define BSLS_ASSERT_OPT_IS_ASSUMED
2031#endif
2032
2033// Indicate when 'BSLS_ASSERT_OPT' arguments will be ODR-used.
2034#if defined(BSLS_ASSERT_OPT_IS_REVIEW) || \
2035 defined(BSLS_ASSERT_OPT_IS_ACTIVE) || \
2036 (defined(BSLS_ASSERT_OPT_IS_ASSUMED) \
2037 && defined(BSLS_ASSERT_ASSUME_ENABLED)) || \
2038 defined(BSLS_ASSERT_VALIDATE_DISABLED_MACROS)
2039 #define BSLS_ASSERT_OPT_IS_USED
2040#endif
2041
2042// Define 'BSLS_ASSERT_OPT' accordingly.
2043
2044#if defined(BSLS_ASSERT_OPT_IS_ACTIVE)
2045 #define BSLS_ASSERT_OPT(X) BSLS_ASSERT_ASSERT_IMP( \
2046 X, \
2047 BloombergLP::bsls::Assert::k_LEVEL_OPT)
2048#elif defined(BSLS_ASSERT_OPT_IS_REVIEW)
2049 #define BSLS_ASSERT_OPT(X) BSLS_REVIEW_REVIEW_IMP( \
2050 X, \
2051 BloombergLP::bsls::Assert::k_LEVEL_OPT)
2052#elif defined(BSLS_ASSERT_OPT_IS_ASSUMED)
2053 #define BSLS_ASSERT_OPT(X) BSLS_ASSERT_ASSUME_IMP( \
2054 X, \
2055 BloombergLP::bsls::Assert::k_LEVEL_OPT)
2056#else
2057 #define BSLS_ASSERT_OPT(X) BSLS_ASSERT_DISABLED_IMP( \
2058 X, \
2059 BloombergLP::bsls::Assert::k_LEVEL_OPT)
2060#endif
2061
2062// Define 'BSLS_ASSERT_OPT_UNREACHABLE' accordingly.
2063
2064#if defined(BSLS_ASSERT_OPT_IS_ACTIVE)
2065 #define BSLS_ASSERT_OPT_UNREACHABLE(X) BSLS_ASSERT_UNREACHABLE_IMP( \
2066 X, \
2067 BloombergLP::bsls::Assert::k_LEVEL_OPT)
2068#elif defined(BSLS_ASSERT_OPT_IS_REVIEW)
2069 #define BSLS_ASSERT_OPT_UNREACHABLE(X) BSLS_REVIEW_UNREACHABLE_IMP( \
2070 X, \
2071 BloombergLP::bsls::Assert::k_LEVEL_OPT)
2072#else
2073 #define BSLS_ASSERT_OPT_UNREACHABLE(X) \
2074 BSLS_ASSERT_UNREACHABLE_DISABLED_IMP( \
2075 X, \
2076 BloombergLP::bsls::Assert::k_LEVEL_OPT)
2077#endif
2078
2079 // ==================
2080 // BSLS_ASSERT_INVOKE
2081 // ==================
2082
2083// 'BSLS_ASSERT_INVOKE' is always active and never in review mode or disabled.
2084#define BSLS_ASSERT_INVOKE(X) do { \
2085 BloombergLP::bsls::Assert::invokeHandler( \
2086 BloombergLP::bsls::AssertViolation( \
2087 X, \
2088 BSLS_ASSERTIMPUTIL_FILE, \
2089 BSLS_ASSERTIMPUTIL_LINE, \
2090 BloombergLP::bsls::Assert::k_LEVEL_INVOKE));\
2091 } while (false)
2092
2093// 'BSLS_ASSERT_INVOKE_NORETURN' is always active and guaranteed to never
2094// return (by calling 'bsls::Assert::failByAbort') even if the installed
2095// handler does return. Note that this macro expands into an infinite loop
2096// (that will always terminate the program in its first iteration) in order to
2097// suppress warnings even on platforms that do not understand the
2098// '[[noreturn]]' attribute. Therefore, this macro can be used to implement
2099// code paths that are meant to be unreachable within functions having non-void
2100// return types.
2101#define BSLS_ASSERT_INVOKE_NORETURN(X) do { \
2102 BloombergLP::bsls::Assert::invokeHandlerNoReturn( \
2103 BloombergLP::bsls::AssertViolation( \
2104 X, \
2105 BSLS_ASSERTIMPUTIL_FILE, \
2106 BSLS_ASSERTIMPUTIL_LINE, \
2107 BloombergLP::bsls::Assert::k_LEVEL_INVOKE));\
2108 } while (true)
2109
2110
2111 // ===================================
2112 // BSLS_ASSERT_NORETURN_INVOKE_HANDLER
2113 // ===================================
2114
2115#ifdef BSLS_ASSERT_ENABLE_NORETURN_FOR_INVOKE_HANDLER
2116#define BSLS_ASSERT_NORETURN_INVOKE_HANDLER BSLS_ANNOTATION_NORETURN
2117#else
2118#define BSLS_ASSERT_NORETURN_INVOKE_HANDLER BSLS_ANNOTATION_ANALYZER_NORETURN
2119// Even in cases where we might allow potentially returning from the violation
2120// handler, it is still preferable for static analysis tools to not produce
2121// extraneous warnings about the branches where an assertion has been violated.
2122#endif
2123
2124// A nested include guard is needed to support the test driver implementation.
2125#ifndef BSLS_ASSERT_RECURSIVELY_INCLUDED_TESTDRIVER_GUARD
2126#define BSLS_ASSERT_RECURSIVELY_INCLUDED_TESTDRIVER_GUARD
2127
2128
2129namespace bsls {
2130
2131 // =====================
2132 // class AssertViolation
2133 // =====================
2134
2135/// This class is an unconstrained *in-core* value-semantic class that
2136/// characterizes the details of a assert failure that has occurred.
2137///
2138/// See @ref bsls_assert
2140
2141 // DATA
2142 const char *d_comment_p; // the comment associated with the violation,
2143 // generally representing the expression that
2144 // failed
2145
2146 const char *d_fileName_p; // the name of the file where the violation
2147 // occurred
2148
2149 int d_lineNumber; // the line number where the violation
2150 // occurred
2151
2152 const char *d_assertLevel_p; // the level and type of the violation that
2153 // occurred, generally one of the 'k_LEVEL'
2154 // constants defined in 'bsls::Review' or
2155 // 'bsls::Assert'
2156
2157 public:
2158 // CREATORS
2159
2160 /// Create a `AssertViolation` with the specified `comment`, `fileName`, `lineNumber`, and `assertLevel`.
2161 ///
2162 /// \note Note that the supplied
2163 /// `assertLevel` will usually be one of the `k_LEVEL` constants defined
2164 /// in `bsls::Assert`
2166 AssertViolation(const char *comment,
2167 const char *fileName,
2168 int lineNumber,
2169 const char *assertLevel);
2170
2171 // ACCESSORS
2172
2173 /// Return the `assertLevel` attribute of this object.
2174 const char *assertLevel() const;
2175
2176 /// Return the `comment` attribute of this object.
2177 const char *comment() const;
2178
2179 /// Return the `fileName` attribute of this object.
2180 const char *fileName() const;
2181
2182 /// Return the `lineNumber` attribute of this object.
2183 int lineNumber() const;
2184};
2185
2186 // ============
2187 // class Assert
2188 // ============
2189
2190/// This "utility" class maintains a pointer containing the address of the
2191/// current assertion-failure handler function (of type
2192/// `Assert::ViolationHandler`) and provides methods to administer this
2193/// function pointer. The `invokeHandler` method calls the
2194/// currently-installed failure handler. This class also provides a suite
2195/// of standard failure-handler functions that are suitable to be installed as the current `Assert::ViolationHandler` function.
2196///
2197/// \note Note that clients
2198/// are free to install any of these ("off-the-shelf") handlers, or to
2199/// provide their own ("custom") assertion-failure handler functions when
2200/// using this facility. Also note that assertion-failure handler functions
2201/// must not return (i.e., they must `abort`, `exit`, `terminate`, `throw`,
2202/// or hang).
2203///
2204/// Finally, this class defines the constant strings that are passed as the
2205/// `reviewLevel` to the @ref bsls_review handler for checks that failed in
2206/// "review mode" (see {Assertion Modes}).
2207///
2208/// See @ref bsls_assert
2209class Assert {
2210
2211 public:
2212 // TYPES
2213
2214 /// `ViolationHandler` is an alias for a pointer to a function returning
2215 /// `void`, and taking, as a parameter a single `const` reference to a
2216 /// `bsls::AssertViolation` -- e.g.,
2217 /// @code
2218 /// void myHandler(const bsls::AssertViolation&);
2219 /// @endcode
2220 typedef void (*ViolationHandler)(const AssertViolation&);
2221
2222 /// `Handler` is an alias for a pointer to a function returning `void`,
2223 /// and taking, as parameters, two null-terminated strings and an `int`,
2224 /// which is the structure of all assertion-failure handler functions
2225 /// supported by this class -- e.g.,
2226 /// @code
2227 /// void myHandler(const char *text, const char *file, int line);
2228 /// @endcode
2229 typedef void (*Handler)(const char *, const char *, int);
2230
2231 private:
2232 // FRIENDS
2234
2235 // PRIVATE CLASS METHODS
2236
2237 /// Make the specified handler `function` the current assertion-failure
2238 /// handler.
2239 static void setViolationHandlerRaw(Assert::ViolationHandler function);
2240
2241 /// Make the specified `function` the current legacy handler and set the
2242 /// current assertion-failure handler to `failOnViolation`.
2243 static void setFailureHandlerRaw(Assert::Handler function);
2244
2245 /// Get the `comment`, `fileName`, and `lineNumber` from the specified
2246 /// `violation` and pass them to the registered `Handler`. This
2247 /// function exists to provide support for the older signature for
2248 /// assertion-failure handlers specified by `Handler`.
2249 static void failOnViolation(const AssertViolation& violation);
2250
2251 public:
2252 // PUBLIC CONSTANTS
2253
2254 // 'assertLevel' Strings
2255
2256 static const char k_LEVEL_SAFE[];
2257 static const char k_LEVEL_OPT[];
2258 static const char k_LEVEL_ASSERT[];
2259 static const char k_LEVEL_INVOKE[];
2260
2261 // PUBLIC CLASS DATA
2263 // This constant has the value "No".
2264 // See {Assertion Handler Policy}.
2265
2266 // CLASS METHODS
2267
2268 // Administrative Methods
2269
2270 /// Make the specified violation handler `function` the current
2271 /// assertion-failure handler. This method has no effect if the
2272 /// `lockAssertAdministration` method has been called.
2274
2275 /// Make the specified handler `function` the current assertion-failure
2276 /// handler. This method has no effect if the
2277 /// `lockAssertAdministration` method has been called.
2278 static void setFailureHandler(Assert::Handler function);
2279
2280 /// Disable all subsequent calls to `setFailureHandler`.
2281 /// \note Note that this
2282 /// method has no effect on the behavior of a
2283 /// `AssertFailureHandlerGuard` object.
2285
2286 /// Return the address of the currently installed assertion-failure
2287 /// handler function if it is a `Handler` (and not a
2288 /// `ViolationHandler`); otherwise, return `NULL`.
2290
2291 /// Return the address of the currently installed assertion-failure
2292 /// handler function.
2294
2295 // Dispatcher Method (called from within macros)
2296
2297 /// Invoke the currently installed assertion-failure handler function with the specified `violation`.
2298 ///
2299 /// \pre The behavior is undefined if the
2300 /// macro `BSLS_ASSERT_ENABLE_NORETURN_FOR_INVOKE_HANDLER` is defined,
2301 /// and the currently installed assertion-failure handler function
2302 /// returns to the caller (i.e., the assertion handler does *not* `abort`, `exit`, `terminate`, `throw`, or hang).
2303 ///
2304 /// \note Note that this
2305 /// function is intended for use by the (BSLS) "ASSERT" macros, but may
2306 /// also be called by clients directly as needed (preferably with
2307 /// `BSLS_ASSERT_INVOKE`). Also note that the configuration macro
2308 /// `BSLS_ASSERT_ENABLE_NORETURN_FOR_INVOKE_HANDLER` is intended to
2309 /// support static analysis tools, which require an annotation to see
2310 /// that a failed "ASSERT" prevents further execution of a function with
2311 /// "bad" values.
2313 static void invokeHandler(const AssertViolation& violation);
2314
2315 /// Invoke the currently installed assertion-failure handler function
2316 /// with the specified expression `text`, `file` name, and `line` number as its arguments.
2317 ///
2318 /// \pre The behavior is undefined if the macro
2319 /// `BSLS_ASSERT_ENABLE_NORETURN_FOR_INVOKE_HANDLER` is defined, and the
2320 /// currently installed assertion-failure handler function returns to
2321 /// the caller (i.e., the assertion handler does *not* `abort`, `exit`, `terminate`, `throw`, or hang).
2322 ///
2323 /// \note Note that this function is
2324 /// deprecated, as the (BSLS) "ASSERT" macros all now use the
2325 /// `bsls::AssertViolation` overload of `invokeHandler` instead.
2326 ///
2327 /// @deprecated Use @ref invokeHandler(const AssertViolation&) instead.
2329 static void invokeHandler(const char *text, const char *file, int line);
2330
2331 /// Invoke the currently installed assertion-failure handler function
2332 /// with the specified `violation`. If the handler returns normally,
2333 /// invoke `bsls::Assert::failByAbort`.
2335 static void invokeHandlerNoReturn(const AssertViolation &violation);
2336
2337#ifdef BSLS_ASSERT_USE_CONTRACTS
2338 /// Call `invokeHandler` with an `AssertViolation` with properties from
2339 /// the specified `violation`.
2341 static void invokeLanguageContractHandler(
2342 const std::contract_violation& violation);
2343#endif
2344
2345 // Standard Assertion-Failure Handlers
2346
2347 /// (Default Handler) Emulate the invocation of the standard `assert`
2348 /// macro with a `false` argument, using the expression `comment`,
2349 /// `file` name, and `line` number from the specified `violation` to
2350 /// generate a helpful output message and then, after logging, unconditionally aborting.
2351 ///
2352 /// \note Note that this handler function is the
2353 /// default installed assertion handler.
2355 static void failByAbort(const AssertViolation& violation);
2356
2357 /// Use the expression `comment`, `file` name, and `line` number from
2358 /// the specified `violation` to generate a helpful output message and then, after logging, spin in an infinite loop.
2359 ///
2360 /// \note Note that this
2361 /// handler function is useful for hanging a process so that a debugger
2362 /// may be attached to it.
2364 static void failBySleep(const AssertViolation& violation);
2365
2366 /// Throw an `AssertTestException` whose attributes are the `comemnt`,
2367 /// `file`, `line`, and `level` from the specified `violation` provided
2368 /// that `BDE_BUILD_TARGET_EXC` is defined; otherwise, log an
2369 /// appropriate message and abort the program (similar to
2370 /// `failByAbort`).
2372 static void failByThrow(const AssertViolation& violation);
2373
2374 /// @deprecated Use @ref failByAbort instead.
2375 ///
2376 /// Emulate the invocation of the standard `assert` macro with a `false`
2377 /// argument, using the specified expression `comment`, `file` name, and
2378 /// `line` number to generate a helpful output message and then, after
2379 /// logging, unconditionally aborting.
2381 static void failAbort(const char *comment, const char *file, int line);
2382
2383 /// @deprecated Use @ref failBySleep instead.
2384 ///
2385 /// Use the specified expression `comment`, `file` name, and `line`
2386 /// number to generate a helpful output message and then, after logging, spin in an infinite loop.
2387 ///
2388 /// \note Note that this handler function is useful
2389 /// for hanging a process so that a debugger may be attached to it.
2391 static void failSleep(const char *comment, const char *file, int line);
2392
2393 /// @deprecated Use @ref failByThrow instead.
2394 ///
2395 /// Throw an `AssertTestException` whose attributes are the specified
2396 /// `comemnt`, `file`, `line`, and `level` provided that
2397 /// `BDE_BUILD_TARGET_EXC` is defined; otherwise, log an appropriate
2398 /// message and abort the program (similar to `failAbort`).
2400 static void failThrow(const char *comment, const char *file, int line);
2401
2402
2403 // Assertion Handler Policy Enforcement
2404
2405 /// Return `true` if `k_permitOutOfPolicyReturningAssertionBuildKey`
2406 /// does not have the value "bsls-PermitOutOfPolicyReturn" or
2407 /// `permitOutOfPolicyReturningFailureHandler` has not previously been invoked, and `false` otherwise.
2408 ///
2409 /// \note Note that returning `true`
2410 /// indicates that `bsls::Assert` should abort the task if the currently
2411 /// installed assertion-failure handler returns normally (after the
2412 /// detection of a failed assertion).
2414
2415 /// DO NOT USE! It is a violation of Bloomberg policy to invoke this
2416 /// function without having prior authorization from senior management.
2417 ///
2418 /// Allow an assertion handler to return control to the calling function (after a failed assertion).
2419 ///
2420 /// \pre The behavior is undefined if
2421 /// `BSLS_ASSERT_ENABLE_NORETURN_FOR_INVOKE_HANDLER` is defined (and
2422 /// thus `invokeHandler` would not be able to return anyway).
2423 ///
2424 /// \note Note that, by default, an assertion handler that attempts to return
2425 /// normally will cause the program to be aborted.
2426 ///
2427 /// Internal Bloomberg users should contact the BDE team if they feel
2428 /// their application might need to violate Bloomberg policy by allowing
2429 /// the currently installed assertion handler to return normally (after
2430 /// a failed assertion).
2432};
2433
2434 // ===============================
2435 // class AssertFailureHandlerGuard
2436 // ===============================
2437
2438/// An object of this class saves the current assert handler and installs
2439/// the one specified on construction. On destruction, the original assert handler is restored.
2440///
2441/// \note Note that two objects of this class cannot be
2442/// safely used concurrently from two separate threads (but may of course
2443/// appear sequentially, including in nested blocks and function invocations within a single thread).
2444///
2445/// \note Note that the behavior of objects of this
2446/// class is unaffected by the (`static`) `Assert::lockAssertAdministration`
2447/// method (i.e., the temporary replacement will occur, regardless of
2448/// whether that method has been invoked.)
2449///
2450/// See @ref bsls_assert
2452
2453 // DATA
2454 Assert::ViolationHandler d_original; // original handler
2455 Assert::Handler d_legacyOriginal; // original legacy handler
2456
2457 private:
2458 // NOT IMPLEMENTED
2461
2462 public:
2463 // CREATORS
2464
2465 /// Create a guard object that installs the specified `temporary`
2466 /// failure handler and automatically restores the original handler on
2467 /// destruction.
2470
2471 /// Restore the failure handler that was in place when this object was
2472 /// created and destroy this guard.
2474};
2475
2476} // close package namespace
2477
2478#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
2479
2480// ============================================================================
2481// BACKWARD COMPATIBILITY
2482// ============================================================================
2483
2484// BDE_VERIFY pragma: push
2485// BDE_VERIFY pragma: -SLM01
2486// BDE_VERIFY pragma: -CP01
2487// BDE_VERIFY pragma: -TR04
2488// BDE_VERIFY pragma: -TR17
2489
2490#ifndef BDE_OMIT_INTERNAL_DEPRECATED
2491 // =========================
2492 // BDE_ASSERT_H (deprecated)
2493 // =========================
2494
2495// Active in "Safe Mode"
2496
2497#define BDE_ASSERT_H(X) BSLS_ASSERT_SAFE(X)
2498#define BSL_ASSERT_H(X) BSLS_ASSERT_SAFE(X) // introduced during migration
2499
2500 // ===========================
2501 // BDE_ASSERT_CPP (deprecated)
2502 // ===========================
2503
2504// Active in "Safe Mode" and "Debug Mode"
2505
2506#define BDE_ASSERT_CPP(X) BSLS_ASSERT(X)
2507#define BSL_ASSERT_CPP(X) BSLS_ASSERT(X) // introduced during migration
2508
2509/// This alias is defined for backward compatibility.
2511
2512/// This alias is defined for backward compatibility.
2514
2515 // ==========================
2516 // BSLS_ASSERT_H (deprecated)
2517 // ==========================
2518
2519// Old 'BSLS_ASSERT' implementation macro that was incorrectly used externally.
2520
2521#define BSLS_ASSERT_ASSERT(X) BSLS_ASSERT_ASSERT_IMP( \
2522 X, \
2523 BloombergLP::bsls::Assert::k_LEVEL_ASSERT)
2524
2525#endif // BDE_OMIT_INTERNAL_DEPRECATED
2526
2527/// This alias is defined for backward compatibility.
2529
2530/// This alias is defined for backward compatibility.
2532
2533#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
2534
2535// BDE_VERIFY pragma: pop
2536
2537// ============================================================================
2538// INLINE FUNCTION DEFINITIONS
2539// ============================================================================
2540
2541namespace bsls {
2542 // ---------------------
2543 // class AssertViolation
2544 // ---------------------
2545
2546// CREATORS
2548inline
2550 const char *fileName,
2551 int lineNumber,
2552 const char *assertLevel)
2553: d_comment_p((comment == 0) ? "" : comment)
2554, d_fileName_p((fileName == 0) ? "" : fileName)
2555, d_lineNumber(lineNumber)
2556, d_assertLevel_p((assertLevel == 0) ? "" : assertLevel)
2557{
2558}
2559
2560// ACCESSORS
2561inline
2563{
2564 return d_assertLevel_p;
2565}
2566
2567inline
2568const char *AssertViolation::comment() const
2569{
2570 return d_comment_p;
2571}
2572
2573inline
2574const char *AssertViolation::fileName() const
2575{
2576 return d_fileName_p;
2577}
2578
2579inline
2581{
2582 return d_lineNumber;
2583}
2584
2585} // close package namespace
2586
2587
2588#endif // deeper include guard
2589
2590 // ========================================================
2591 // UNDEFINE THE LOCALLY-SCOPED IMPLEMENTATION DETAIL MACROS
2592 // ========================================================
2593
2594#undef BSLS_ASSERT_NORETURN_INVOKE_HANDLER
2595#undef BSLS_ASSERT_NO_ASSERTION_MACROS_DEFINED
2596#undef BSLS_ASSERT_ASSUME_ENABLED
2597
2598 // =========================================
2599 // IMPLEMENTATION USING THE C++ PREPROCESSOR
2600 // =========================================
2601
2602// At most one of the following build options may be set during the compilation
2603// of any component that includes 'bsls_assert.h':
2604// ```
2605// BSLS_ASSERT_LEVEL_ASSERT_SAFE
2606// BSLS_ASSERT_LEVEL_ASSERT
2607// BSLS_ASSERT_LEVEL_ASSERT_OPT
2608// BSLS_ASSERT_LEVEL_NONE
2609// BSLS_ASSERT_LEVEL_ASSUME_SAFE
2610// BSLS_ASSERT_LEVEL_ASSUME_ASSERT
2611// BSLS_ASSERT_LEVEL_ASSUME_OPT
2612// ```
2613// ----------------------------------------------------------------------------
2614
2615#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
2616 defined(BSLS_ASSERT_LEVEL_ASSERT)
2617#error incompatible BSLS_ASSERT levels: \
2618..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSERT
2619#endif
2620
2621#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
2622 defined(BSLS_ASSERT_LEVEL_ASSERT_OPT)
2623#error incompatible BSLS_ASSERT levels: \
2624..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSERT_OPT
2625#endif
2626
2627#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
2628 defined(BSLS_ASSERT_LEVEL_NONE)
2629#error incompatible BSLS_ASSERT levels: \
2630..._LEVEL_ASSERT_SAFE and ..._LEVEL_NONE
2631#endif
2632
2633#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
2634 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
2635#error incompatible BSLS_ASSERT levels: \
2636..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSUME_OPT
2637#endif
2638
2639#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
2640 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
2641#error incompatible BSLS_ASSERT levels: \
2642..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSUME_ASSERT
2643#endif
2644
2645#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
2646 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
2647#error incompatible BSLS_ASSERT levels: \
2648..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSUME_SAFE
2649#endif
2650
2651#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
2652 defined(BSLS_ASSERT_LEVEL_ASSERT_OPT)
2653#error incompatible BSLS_ASSERT levels: \
2654..._LEVEL_ASSERT and ..._LEVEL_ASSERT_OPT
2655#endif
2656
2657#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
2658 defined(BSLS_ASSERT_LEVEL_NONE)
2659#error incompatible BSLS_ASSERT levels: \
2660..._LEVEL_ASSERT and ..._LEVEL_NONE
2661#endif
2662
2663#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
2664 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
2665#error incompatible BSLS_ASSERT levels: \
2666..._LEVEL_ASSERT and ..._LEVEL_ASSUME_OPT
2667#endif
2668
2669#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
2670 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
2671#error incompatible BSLS_ASSERT levels: \
2672..._LEVEL_ASSERT and ..._LEVEL_ASSUME_ASSERT
2673#endif
2674
2675#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
2676 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
2677#error incompatible BSLS_ASSERT levels: \
2678..._LEVEL_ASSERT and ..._LEVEL_ASSUME_SAFE
2679#endif
2680
2681#if defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) && \
2682 defined(BSLS_ASSERT_LEVEL_NONE)
2683#error incompatible BSLS_ASSERT levels: \
2684..._LEVEL_ASSERT_OPT and ..._LEVEL_NONE
2685#endif
2686
2687#if defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) && \
2688 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
2689#error incompatible BSLS_ASSERT levels: \
2690..._LEVEL_ASSERT_OPT and ..._LEVEL_ASSUME_OPT
2691#endif
2692
2693#if defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) && \
2694 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
2695#error incompatible BSLS_ASSERT levels: \
2696..._LEVEL_ASSERT_OPT and ..._LEVEL_ASSUME_ASSERT
2697#endif
2698
2699#if defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) && \
2700 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
2701#error incompatible BSLS_ASSERT levels: \
2702..._LEVEL_ASSERT_OPT and ..._LEVEL_ASSUME_SAFE
2703#endif
2704
2705#if defined(BSLS_ASSERT_LEVEL_NONE) && \
2706 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
2707#error incompatible BSLS_ASSERT levels: \
2708..._LEVEL_NONE and ..._LEVEL_ASSUME_OPT
2709#endif
2710
2711#if defined(BSLS_ASSERT_LEVEL_NONE) && \
2712 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
2713#error incompatible BSLS_ASSERT levels: \
2714..._LEVEL_NONE and ..._LEVEL_ASSUME_ASSERT
2715#endif
2716
2717#if defined(BSLS_ASSERT_LEVEL_NONE) && \
2718 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
2719#error incompatible BSLS_ASSERT levels: \
2720..._LEVEL_NONE and ..._LEVEL_ASSUME_SAFE
2721#endif
2722
2723#if defined(BSLS_ASSERT_LEVEL_ASSUME_OPT) && \
2724 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
2725#error incompatible BSLS_ASSERT levels: \
2726..._LEVEL_ASSUME_OPT and ..._LEVEL_ASSUME_ASSERT
2727#endif
2728
2729#if defined(BSLS_ASSERT_LEVEL_ASSUME_OPT) && \
2730 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
2731#error incompatible BSLS_ASSERT levels: \
2732..._LEVEL_ASSUME_OPT and ..._LEVEL_ASSUME_SAFE
2733#endif
2734
2735#if defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT) && \
2736 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
2737#error incompatible BSLS_ASSERT levels: \
2738..._LEVEL_ASSUME_ASSERT and ..._LEVEL_ASSUME_SAFE
2739#endif
2740
2741#endif
2742
2743// ----------------------------------------------------------------------------
2744// Copyright 2018 Bloomberg Finance L.P.
2745//
2746// Licensed under the Apache License, Version 2.0 (the "License");
2747// you may not use this file except in compliance with the License.
2748// You may obtain a copy of the License at
2749//
2750// http://www.apache.org/licenses/LICENSE-2.0
2751//
2752// Unless required by applicable law or agreed to in writing, software
2753// distributed under the License is distributed on an "AS IS" BASIS,
2754// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2755// See the License for the specific language governing permissions and
2756// limitations under the License.
2757// ----------------------------- END-OF-FILE ----------------------------------
2758
2759/** @} */
2760/** @} */
2761/** @} */
Definition bsls_assert.h:2451
AssertFailureHandlerGuard(Assert::Handler temporary)
AssertFailureHandlerGuard(Assert::ViolationHandler temporary)
Definition bsls_assert.h:2139
BSLS_KEYWORD_CONSTEXPR AssertViolation(const char *comment, const char *fileName, int lineNumber, const char *assertLevel)
Definition bsls_assert.h:2549
int lineNumber() const
Return the lineNumber attribute of this object.
Definition bsls_assert.h:2580
const char * comment() const
Return the comment attribute of this object.
Definition bsls_assert.h:2568
const char * assertLevel() const
Return the assertLevel attribute of this object.
Definition bsls_assert.h:2562
const char * fileName() const
Return the fileName attribute of this object.
Definition bsls_assert.h:2574
Definition bsls_assert.h:2209
static Assert::ViolationHandler violationHandler()
static BSLS_ANNOTATION_NORETURN void invokeHandlerNoReturn(const AssertViolation &violation)
static BSLS_ANNOTATION_NORETURN void failSleep(const char *comment, const char *file, int line)
static const char k_LEVEL_ASSERT[]
Definition bsls_assert.h:2258
static void setViolationHandler(Assert::ViolationHandler function)
static void lockAssertAdministration()
static const char k_LEVEL_SAFE[]
Definition bsls_assert.h:2256
static Assert::Handler failureHandler()
static BSLS_ASSERT_NORETURN_INVOKE_HANDLER void invokeHandler(const char *text, const char *file, int line)
static BSLS_ANNOTATION_NORETURN void failByThrow(const AssertViolation &violation)
static BSLS_ANNOTATION_NORETURN void failBySleep(const AssertViolation &violation)
static bool abortUponReturningAssertionFailureHandler()
static void setFailureHandler(Assert::Handler function)
static BSLS_ANNOTATION_NORETURN void failAbort(const char *comment, const char *file, int line)
static BSLS_ANNOTATION_NORETURN void failByAbort(const AssertViolation &violation)
static void permitOutOfPolicyReturningFailureHandler()
void(* Handler)(const char *, const char *, int)
Definition bsls_assert.h:2229
static BSLS_ASSERT_NORETURN_INVOKE_HANDLER void invokeHandler(const AssertViolation &violation)
static const char k_LEVEL_INVOKE[]
Definition bsls_assert.h:2259
static const char k_LEVEL_OPT[]
Definition bsls_assert.h:2257
void(* ViolationHandler)(const AssertViolation &)
Definition bsls_assert.h:2220
static const char * k_permitOutOfPolicyReturningAssertionBuildKey
Definition bsls_assert.h:2262
static BSLS_ANNOTATION_NORETURN void failThrow(const char *comment, const char *file, int line)
#define BSLS_ANNOTATION_ANALYZER_NORETURN
Definition bsls_annotation.h:391
#define BSLS_ANNOTATION_NORETURN
Definition bsls_annotation.h:378
bsls::Assert bsls_Assert
This alias is defined for backward compatibility.
Definition bsls_assert.h:2528
bsls::AssertFailureHandlerGuard bsls_AssertFailureHandlerGuard
This alias is defined for backward compatibility.
Definition bsls_assert.h:2531
bsls::AssertFailureHandlerGuard bdes_AssertFailureHandlerGuard
This alias is defined for backward compatibility.
Definition bsls_assert.h:2513
#define BSLS_ASSERT_NORETURN_INVOKE_HANDLER
Definition bsls_assert.h:2118
bsls::Assert bdes_Assert
This alias is defined for backward compatibility.
Definition bsls_assert.h:2510
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:624
Definition bdlt_iso8601util.h:707