Ruby: include/ruby/assert.h Source File

Ruby 3.3.6p108 (2024-11-05 revision 75015d4c1f6965b5e85e96fb309f1f2129f933c0)

assert.h
Go to the documentation of this file.
1#ifndef RUBY_ASSERT_H /*-*-C++-*-vi:se ft=cpp:*/
2#define RUBY_ASSERT_H
23#include "ruby/internal/assume.h"
24#include "ruby/internal/attr/cold.h"
25#include "ruby/internal/attr/noreturn.h"
26#include "ruby/internal/cast.h"
27#include "ruby/internal/dllexport.h"
28#include "ruby/backward/2/assume.h"
29
30/* RUBY_NDEBUG is very simple: after everything described below are done,
31 * define it with either NDEBUG is undefined (=0) or defined (=1). It is truly
32 * subordinate.
33 *
34 * RUBY_DEBUG versus NDEBUG is complicated. Assertions shall be:
35 *
36 * | -UNDEBUG | -DNDEBUG
37 * ---------------+----------+---------
38 * -URUBY_DEBUG | (*1) | disabled
39 * -DRUBY_DEBUG=0 | disabled | disabled
40 * -DRUBY_DEBUG=1 | enabled | (*2)
41 * -DRUBY_DEBUG | enabled | (*2)
42 *
43 * where:
44 *
45 * - (*1): Assertions shall be silently disabled, no warnings, in favour of
46 * commit 21991e6ca59274e41a472b5256bd3245f6596c90.
47 *
48 * - (*2): Compile-time warnings shall be issued.
49 */
50
53/*
54 * Pro tip: `!!RUBY_DEBUG-1` expands to...
55 *
56 * - `!!(-1)` (== `!0` == `1`) when RUBY_DEBUG is defined to be empty,
57 * - `(!!0)-1` (== `0-1` == `-1`) when RUBY_DEBUG is defined as 0, and
58 * - `(!!n)-1` (== `1-1` == `0`) when RUBY_DEBUG is defined as something else.
59 */
60#if ! defined(RUBY_DEBUG)
61# define RBIMPL_RUBY_DEBUG 0
62#elif !!RUBY_DEBUG-1 < 0
63# define RBIMPL_RUBY_DEBUG 0
64#else
65# define RBIMPL_RUBY_DEBUG 1
66#endif
67
68/*
69 * ISO/IEC 9899 (all past versions) says that "If NDEBUG is defined as a macro
70 * name at the point in the source file where <assert.h> is included, ..."
71 * which means we must not take its defined value into account.
72 */
73#if defined(NDEBUG)
74# define RBIMPL_NDEBUG 1
75#else
76# define RBIMPL_NDEBUG 0
77#endif
78
81/* Here we go... */
82#undef RUBY_DEBUG
83#undef RUBY_NDEBUG
84#undef NDEBUG
85#if defined(__DOXYGEN__)
86#
87# define RUBY_DEBUG 0
88#
89# define NDEBUG
90#
91# define RUBY_NDEBUG 1
92
93#elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 0)
94# /* Assertions disabled as per request, no conflicts. */
95# define RUBY_DEBUG 0
96# define RUBY_NDEBUG 1
97# define NDEBUG
98
99#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 1)
100# /* Assertions enabled as per request, no conflicts. */
101# define RUBY_DEBUG 1
102# define RUBY_NDEBUG 0
103# /* keep NDEBUG undefined */
104
105#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 0)
106# /* The (*1) situation in above diagram. */
107# define RUBY_DEBUG 0
108# define RUBY_NDEBUG 1
109# define NDEBUG
110
111#elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 1)
112# /* The (*2) situation in above diagram. */
113# define RUBY_DEBUG 1
114# define RUBY_NDEBUG 0
115# /* keep NDEBUG undefined */
116
117# if defined(_MSC_VER)
118# pragma message("NDEBUG is ignored because RUBY_DEBUG>0.")
119# elif defined(__GNUC__)
120# pragma GCC warning "NDEBUG is ignored because RUBY_DEBUG>0."
121# else
122# error NDEBUG is ignored because RUBY_DEBUG>0.
123# endif
124#endif
125#undef RBIMPL_NDEBUG
126#undef RBIMPL_RUBY_DEBUG
127
129#define RBIMPL_ASSERT_NOTHING RBIMPL_CAST((void)0)
130
131 RBIMPL_SYMBOL_EXPORT_BEGIN()
132 RBIMPL_ATTR_NORETURN()
133 RBIMPL_ATTR_COLD()
134void rb_assert_failure(const char *file, int line, const char *name, const char *expr);
135 RBIMPL_SYMBOL_EXPORT_END()
136
137#ifdef RUBY_FUNCTION_NAME_STRING
138# define RBIMPL_ASSERT_FUNC RUBY_FUNCTION_NAME_STRING
139#else
140# define RBIMPL_ASSERT_FUNC RBIMPL_CAST((const char *)0)
141#endif
142
150#define RUBY_ASSERT_FAIL(mesg) \
151 rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
152
159#define RUBY_ASSERT_MESG(expr, mesg) \
160 (RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(mesg))
161
167#define RUBY_ASSERT_ALWAYS(expr) RUBY_ASSERT_MESG((expr), #expr)
168
174#if RUBY_DEBUG
175# define RUBY_ASSERT(expr) RUBY_ASSERT_MESG((expr), #expr)
176#else
177# define RUBY_ASSERT(expr) RBIMPL_ASSERT_NOTHING
178#endif
179
187/* Currently `RUBY_DEBUG == ! defined(NDEBUG)` is always true. There is no
188 * difference any longer between this one and `RUBY_ASSERT`. */
189#if defined(NDEBUG)
190# define RUBY_ASSERT_NDEBUG(expr) RBIMPL_ASSERT_NOTHING
191#else
192# define RUBY_ASSERT_NDEBUG(expr) RUBY_ASSERT_MESG((expr), #expr)
193#endif
194
199#if RUBY_DEBUG
200# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) RUBY_ASSERT_MESG((expr), (mesg))
201#else
202# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
203 ((cond) ? RUBY_ASSERT_MESG((expr), (mesg)) : RBIMPL_ASSERT_NOTHING)
204#endif
205
213#define RUBY_ASSERT_WHEN(cond, expr) RUBY_ASSERT_MESG_WHEN((cond), (expr), #expr)
214
220#if RUBY_DEBUG
221# define RBIMPL_ASSERT_OR_ASSUME(expr) RUBY_ASSERT_ALWAYS(expr)
222#elif RBIMPL_COMPILER_BEFORE(Clang, 7, 0, 0)
223# /* See commit 67d259c5dccd31fe49d417fec169977712ffdf10 */
224# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
225#elif defined(RUBY_ASSERT_NOASSUME)
226# /* See commit d300a734414ef6de7e8eb563b7cc4389c455ed08 */
227# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
228#elif ! defined(RBIMPL_HAVE___ASSUME)
229# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
230#else
231# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSUME(expr)
232#endif
233
234#endif /* RUBY_ASSERT_H */
assume.h
Defines ASSUME / RB_LIKELY / UNREACHABLE.
cold.h
Defines RBIMPL_ATTR_COLD.
RBIMPL_ATTR_COLD
#define RBIMPL_ATTR_COLD()
Wraps (or simulates) __attribute__((cold))
Definition cold.h:34
dllexport.h
Tweaking visibility of C variables/functions.
RBIMPL_SYMBOL_EXPORT_END
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
Definition dllexport.h:74
RBIMPL_SYMBOL_EXPORT_BEGIN
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Definition dllexport.h:65
assume.h
Defines RBIMPL_ASSUME / RBIMPL_UNREACHABLE.
noreturn.h
Defines RBIMPL_ATTR_NORETURN.
RBIMPL_ATTR_NORETURN
#define RBIMPL_ATTR_NORETURN()
Wraps (or simulates) [[noreturn]]
Definition noreturn.h:38