assertf.h
assertf.h is a header-only formattable assert macros library, a possible alternative to the #include <assert.h>.
With enhanced assertions, we can debug/test code better.
Platform
assertf.h originally targets to embedded systems, it also can be used nearly all UNIX-like, including Windows systems.
Example
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#define ASSERTF_DEF_ONCE
#include "assertf.h"
int main(void)
{
int e = rmdir("/tmp");
assert_eqf(e, 0, %d, "rmdir(2) fail, errno: %d", errno); /* Line 11 */
// #define EACCES 13 /* Permission denied */
return 0;
}
Sample assertion failure output(try it online)

Integration
In order to deploy assertf.h to your existing C/C++ project, you need:
-
Download
assertf.hto your source code directory - In one of your C/C++ file(typically project main file), write:
// Define ASSERTF_DEF_ONCE once and only once #define ASSERTF_DEF_ONCE #include "assertf.h" -
If other C/C++ files needs to use
assertf.h, just type#include "assertf.h". - If you want to disable
assertf.hon release build, please specify-DASSERTF_DISABLEinMakefile,CMakeLists.txt, etc.
API
Nearly all assertf.h APIs prefixed with assert, the most basic API is the
-
assertf(expr, fmt, ...)When
exprisnโt true, itโll print out a message backed byfmtand...tostderrand then crash the whole program(ifassertf.his enabled).Sample output:
// assertf(e == 0, "unlink(2) errno: %d", errno); Assert (e == 0) failed: unlink(2) errno: 2 [test.c:12 (main)] [1] 62760 abort (core dumped) ./test -
panicf(fmt, ...)Alias call of
assertf(0, fmt, ...). -
assert_nonnull(ptr),assert_null(ptr)Assert nullability of
ptr. -
assert_eq(a, b, fs),assert_ne(),assert_lt(),assert_le(),assert_gt(),assert_ge()Check arithmetic relation of
aandb,fsis the format specifier ofa,bwill use the same format specifier asa, double-quote in"%<type_specifier>"can be omitted.// assert_eq(e, 0, %d); Assert ((e) == (__type0(e)) (0)) failed: lhs: -1 rhs: 0 [test.c:13 (main)] [1] 65959 abort (core dumped) ./test -
assert_eqf(a, b, fs, fmt, ...),assert_nef(),assert_ltf(),assert_lef(),assert_gtf(),assert_gef()Like above version,
fmtand...can used for verbose assertion output once it failed.// assert_eqf(e, 0, %d, "unlink(2) errno: %d", errno); Assert ((e) == (__type0(e)) (0)) failed: lhs: -1 rhs: 0 unlink(2) errno: 2 [test.c:14 (main)] [1] 66800 abort (core dumped) ./test -
assert_true(x, fs),assert_truef(x, fs, fmt, ...),assert_false(),assert_falsef()Alias call of
assert_ne(x, 0, fs, ...),assert_eq(x, 0, fs, ...). -
assert_nonzero(x, fs),assert_zero(x, fs)Alias call of
assert_true(x, fs),assert_false(x, fs). -
BUILD_BUG_ON()Break compile if a condition is true at compile-time, taken from Linux kernel. Itโs useful with companion of
assert*.If you have some code which relies on certain constants being true, or some other compile-time evaluated condition, you should use
BUILD_BUG_ON()to detect if someone changes it unexpectedly.
Caveats
-
Do NOT
#define ASSERTF_DISABLEin any part of your project source code, itโll break compilation semantics ofassertf.h. Like aforementioned, define it inMakefile,CMakeLists.txt, etc. -
Like
#include <assert.h>, allassertf.hAPIs isnโt side-effect safe. -
Like
#include <assert.h>, when theexprnot true,abort(3)will be called eventually. -
Some C/C++ compilers may warns you
implicit declaration of function 'typeof' is invalid in C99 [-Wimplicit-function-declaration], in such case, you may replace thetypeofwith__typeof__and try again.
Pro tips
-
Do NOT misuse any assertion library, assertion is very useful in software development, many people rely on it heavily and some certainly misused it.
Use assertion to assure code quality isnโt a decent way to solve the problem.
Most software have a very long life-time, sometimes keep running is better than simply crashed.
SEE ALSO: Why does Go not have assertions?
-
Do NOT write side-effect unsafe code:
// When you -DASSERTF_DISABLE, lseek(2) may optimized out by the compiler. assert_gt(lseek(fd, offset, SEEK_CUR), 0, %d);// The ++i will be evaluated twice when expanding assert_eq() macro // Again, -DASSERTF_DISABLE may cause ++i optimized out by the compiler assert_eq(++i, n, %d); -
Use
assertf.hheavily and confidently in your code base. -
Replace
#include <assert.h>with#include "assertf.h". ๐
FAQ
-
HOWTO check if
assertf.hdisabled on a certain build?-
UNIX-like systems
$ nm some_binary | grep assertf 0000000000007709 T x_assertf_c21162d2If you see
x_assertf_c21162d2, it meansassertf.his enabled insome_binary.Note that if you
strip(1)the symbols, you have no way to determine whetherassertf.hdisabled or not. -
Windows
You need have to check the
pdb(Program database) file.
-