1/* 2 advanced assert() definition 3 4 code under LGPL 5 created by Albert Zeyer, on 15-03-2009 6*/ 7 8#include <cctype> 9 10 11#ifndef TOSTRING 12#define STRINGIFY(x) #x 13#define TOSTRING(x) STRINGIFY(x) 14#endif 15 16 17#undef assert_failed 18#ifdef _MSC_VER 19# define assert_failed(x) { printf("Assertion %s failed: %s in %s:%i\n", TOSTRING(x), (__FUNCSIG__), (__FILE__), (__LINE__)); __asm { int 3 }; } 20#else 21# ifdef __GNUC__ 22# define assert_failed(x) { printf("Assertion %s failed: %s in %s:%i\n", TOSTRING(x), __FUNCTION__, __FILE__, __LINE__); abort(); } 23# else 24# define assert_failed(x) { printf("Assertion %s failed: in %s:%i\n", TOSTRING(x), __FILE__, __LINE__); abort(); } 25# endif 26#endif 27 28 29#undef rt_assert 30#define rt_assert(x) { if(!(x)) { assert_failed(x); } } 31 32 33// We will get multiple compiler errors for this (and we want these). 34// It should give a linker error for an unresolved symbol. 35void assert_failed_statically (void) 36#if defined(__GNUC__) && __GNUC_PREREQ(4,3) 37// In this case, we can print an error even earlier. 38__attribute__((error("assertion always false"))) 39#endif 40; 41 42 43#undef is_known_at_ct 44#ifdef __GNUC__ 45# define is_known_at_ct(x) __builtin_constant_p(x) 46#else 47// TODO ... 48# define is_known_at_ct(x) 0 49#endif 50 51 52#undef assert 53#define assert(x) { \ 54 if(is_known_at_ct(!(x))) { \ 55 if(strcmp(TOSTRING(x), "false") == 0) { rt_assert(x); } \ 56 else if(!(x)) assert_failed_statically(); } \ 57 else rt_assert(x); } 58 59