diff options
| -rw-r--r-- | include/al/lib.h | 32 | ||||
| -rw-r--r-- | meson.build | 27 |
2 files changed, 42 insertions, 17 deletions
diff --git a/include/al/lib.h b/include/al/lib.h index 5e65149..f5379e5 100644 --- a/include/al/lib.h +++ b/include/al/lib.h @@ -15,7 +15,10 @@ // https://forum.vcfed.org/index.php?threads/c-item-size-check-at-compile-time.1244920/ #define AL_ASSERT_TYPE_SIZE(type, size) \ - typedef char type##__size_test[(!!(sizeof(type) == size)) * 2 - 1] + typedef char type##__size_assert[(!!(sizeof(type) == size)) * 2 - 1] + +#define AL_STATIC_ASSERT(what, a, cmp, b) \ + typedef char what##__assert[(!!(a cmp b)) * 2 - 1] #define AL_USE_STDLIB //#define AL_PARANOID_REALLOC @@ -43,13 +46,6 @@ #include <wchar.h> #include <stdio.h> #include <stdarg.h> -#if !defined AL_DEBUG && defined AL_RELEASE_ASSERTS -#undef NDEBUG -#include <assert.h> -#define NDEBUG -#else -#include <assert.h> -#endif #include <ctype.h> #ifdef AL_MEMORY_TRACKING @@ -100,12 +96,23 @@ static inline void *al_realloc(void *ptr, size_t n) { return ptr ? realloc(ptr, #define al_snprintf snprintf #define al_vsnprintf vsnprintf #define al_fflush fflush -#if defined AL_DEBUG || defined AL_RELEASE_ASSERTS -#define al_assert assert + +#if (defined AL_DEBUG || defined AL_RELEASE_ASSERTS) && defined AL_ASSERT_FUNCTION +#include <assert.h> +// Directly define al_assert() as <assert.h> would if NDEBUG was not set. +#if defined AL_ASSERT_INCLUDE_FUNC +#define al_assert(expr) ((expr) ? (void)0 : AL_ASSERT_FUNCTION(#expr, __FILE__, __LINE__, __func__)) +#elif defined AL_ASSERT_EXPR_LAST +#define al_assert(expr) ((expr) ? (void)0 : AL_ASSERT_FUNCTION(__FILE__, __LINE__, #expr)) #else -#define al_assert(expr) do { (void)sizeof(expr); } while (0) // NOLINT(bugprone-sizeof-expression) +#define al_assert(expr) ((expr) ? (void)0 : AL_ASSERT_FUNCTION(#expr, __FILE__, __LINE__)) #endif - +// Loosely assert that <assert.h> behaves as we expect and redefines itself on every include. +#undef assert +#else +#define al_assert(expr) ((void)sizeof(expr)) // NOLINT(bugprone-sizeof-expression) +#endif +// Use __VA_ARGS__ to allow for an empty return. #define al_assert_and_return(...) do { \ al_assert(false); \ return __VA_ARGS__; \ @@ -181,7 +188,6 @@ static inline char *al_memdup0(const char *s, size_t n) buf[n] = '\0'; return buf; } - #endif static inline u32 al_next_power_of_two(u32 n) diff --git a/meson.build b/meson.build index 285af45..c948887 100644 --- a/meson.build +++ b/meson.build @@ -24,16 +24,35 @@ have_wide_string_width = compiler.has_function('wcswidth') # For testing: '-Wshadow', '-Wconversion', '-Wc++-compat' alabaster_args = ['-fstrict-aliasing', '-Wstrict-aliasing'] -if get_option('release-asserts') - alabaster_args += ['-DAL_RELEASE_ASSERTS'] -endif - if is_debug alabaster_args += ['-DAL_DEBUG'] +elif get_option('release-asserts') + # It's possible that some external code would rely on NDEBUG for conditionally + # excluding something other than asserts. The trade-off here is to accept that rather + # than possibly miss an assert. + alabaster_args += ['-DAL_RELEASE_ASSERTS'] else alabaster_args += ['-DNDEBUG'] endif +# The definition of the assert() macro is determined by the _last_ place where +# <assert.h> was included, because it redefines itself each time. Making it +# unnecessarily complicated to predict if assert() will be active or a no-op. +# Maybe I just haven't seen why this could make sense but to me it's counterintuitive. +# We define al_assert() to be unchanging and let any dependencies figure it out for themselves. +# Another note, which I hadn't heard before but, this clearly makes relying on NDEBUG +# for anything other than asserts a very bad practice. +# https://sourceware.org/git/?p=glibc.git;a=blob;f=assert/assert.h;h=31892aebcb9115a3b48be4d179eb9e8ab2f8784f;hb=HEAD#l24 +if compiler.has_function('__assert_fail', prefix: '#include <assert.h>') + alabaster_args += ['-DAL_ASSERT_FUNCTION=__assert_fail', '-DAL_ASSERT_INCLUDE_FUNC'] +elif compiler.has_function('_assert', prefix: '#include <assert.h>') + # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/assert-macro-assert-wassert?view=msvc-170 + alabaster_args += ['-DAL_ASSERT_FUNCTION=_assert'] +elif compiler.has_function('__assert', prefix: '#include <assert.h>') + # https://github.com/aosp-mirror/platform_bionic/blob/731631f300090436d7f5df80d50b6275c8c60a93/libc/include/assert.h#L63 + alabaster_args += ['-DAL_ASSERT_FUNCTION=__assert', '-DAL_ASSERT_EXPR_LAST'] +endif + if is_msvc_specifically alabaster_args += ['/arch:AVX'] endif |