From bcb89e0554e43d37daf74b3ef6e466b6630752cd Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 5 Feb 2024 11:29:12 +0100 Subject: Custom debuggable ASSERT macro --- src/Common/Assert.hpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/Common/Assert.hpp (limited to 'src/Common/Assert.hpp') diff --git a/src/Common/Assert.hpp b/src/Common/Assert.hpp new file mode 100644 index 0000000..9fc84ce --- /dev/null +++ b/src/Common/Assert.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + +// https://stackoverflow.com/a/26100478/11342122 +// Two levels are needed to make sure that the argument is expanded before stringification +#define _ASSERT_IS_DEFINED(x) _ASSERT_IS_DEFINED2(x) +// TODO: This doesn't compile away on -O0, but it's not a big deal +#define _ASSERT_IS_DEFINED2(x) (#x[0] == 0 || (#x[0] >= '1' && #x[0] <= '9')) + +// Stopping macro, non-fatal in debug mode +#define _ASSERT_STOP (_ASSERT_IS_DEFINED(NDEBUG) ? std::abort() : (void)raise(SIGTRAP)) + +// Assertion message macros, with optional message +#define _ASSERT_NOTIFY_NO_MESSAGE(start) std::fprintf(stderr, start ".\n", __FILE__, __LINE__) +#define _ASSERT_NOTIFY_WITH_MESSAGE(start, message) std::fprintf(stderr, start ": %s\n", __FILE__, __LINE__, message "") +#define _ASSERT_NOTIFY(start, ...) ((strcmp(__VA_ARGS__ "", "") == 0) ? _ASSERT_NOTIFY_NO_MESSAGE(start) : _ASSERT_NOTIFY_WITH_MESSAGE(start, __VA_ARGS__)) + +// Debuggable assertion macro, with optional message +#define ASSERT(condition, ...) do { \ + if (__builtin_expect(!(condition), 0)) { \ + _ASSERT_NOTIFY("ASSERT(" #condition ") failed at %s:%d", __VA_ARGS__); \ + _ASSERT_STOP; \ + } \ +} while (0) + +// Debuggable unreachable macro, with optional message +#define UNREACHABLE(...) do { \ + _ASSERT_NOTIFY("UNREACHABLE() reached at %s:%d", __VA_ARGS__); \ + _ASSERT_STOP; \ +} while (0) \ No newline at end of file -- cgit 1.4.1