Skip to content

Commit

Permalink
Assertion overhaul (#1080)
Browse files Browse the repository at this point in the history
New macros:

* OSL_ASSERT / OSL_ASSERT_MSG -- always test, always print error if the
  test fails, abort only in debug build.

* OSL_DASSERT / OSL_DASSERT_MSG -- debug mode only test, print, abort.
  Does nothing for release build.

Eschew the old OIIO macros ASSERT/DASSERT, since it is perferable to not
purposely abort when in release mode.

Ported over from OIIO copies of a few other related macros.

This patch just adds definitions, we will change the existing macros
in subsequent PRs.
  • Loading branch information
lgritz committed Nov 27, 2019
1 parent edc52c0 commit 1e68690
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/include/OSL/oslconfig.h
Expand Up @@ -187,4 +187,63 @@ using OIIO::cspan;
# define OSL_ALIGNAS(size) alignas(size)
#endif


// OSL_PRETTY_FUNCTION gives a text string of the current function
// declaration.
#if defined(__PRETTY_FUNCTION__)
# define OSL_PRETTY_FUNCTION __PRETTY_FUNCTION__ /* gcc, clang */
#elif defined(__FUNCSIG__)
# define OSL_PRETTY_FUNCTION __FUNCSIG__ /* MS gotta be different */
#else
# define OSL_PRETTY_FUNCTION __FUNCTION__
#endif



/// OSL_ABORT_IF_DEBUG is a call to abort() for debug builds, but does
/// nothing for release builds.
#ifndef NDEBUG
# define OSL_ABORT_IF_DEBUG abort()
#else
# define OSL_ABORT_IF_DEBUG (void)0
#endif

/// OSL_ASSERT(condition) checks if the condition is met, and if not,
/// prints an error message indicating the module and line where the error
/// occurred, and additionally aborts if in debug mode. When in release
/// mode, it prints the error message if the condition fails, but does not
/// abort.
///
/// OSL_ASSERT_MSG(condition,msg,...) lets you add formatted output (a la
/// printf) to the failure message.
#define OSL_ASSERT(x) \
(OIIO_LIKELY(x) \
? ((void)0) \
: (std::fprintf(stderr, "%s:%u: %s: Assertion '%s' failed.\n", \
__FILE__, __LINE__, OSL_PRETTY_FUNCTION, #x), \
OSL_ABORT_IF_DEBUG))
#define OSL_ASSERT_MSG(x, msg, ...) \
(OIIO_LIKELY(x) \
? ((void)0) \
: (std::fprintf(stderr, "%s:%u: %s: Assertion '%s' failed: " msg "\n", \
__FILE__, __LINE__, OSL_PRETTY_FUNCTION, #x, \
__VA_ARGS__), \
OSL_ABORT_IF_DEBUG))

/// OSL_DASSERT and OSL_DASSERT_MSG are the same as OSL_ASSERT for debug
/// builds (test, print error, abort), but do nothing at all in release
/// builds (not even perform the test). This is similar to C/C++ assert(),
/// but gives us flexibility in improving our error messages. It is also ok
/// to use regular assert() for this purpose if you need to eliminate the
/// dependency on this header from a particular place (and don't mind that
/// assert won't format identically on all platforms).
#ifndef NDEBUG
# define OSL_DASSERT OSL_ASSERT
# define OSL_DASSERT_MSG OSL_ASSERT_MSG
#else
# define OSL_DASSERT(x) ((void)sizeof(x)) /*NOLINT*/
# define OSL_DASSERT_MSG(x, ...) ((void)sizeof(x)) /*NOLINT*/
#endif


OSL_NAMESPACE_EXIT

0 comments on commit 1e68690

Please sign in to comment.