Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

leiless/assertf.h

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

42 Commits

Repository files navigation

assertf.h

Try it online Codacy Badge License

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

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)

Samplt output

Integration

In order to deploy assertf.h to your existing C/C++ project, you need:

  1. Download assertf.h to your source code directory

  2. 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"
  3. If other C/C++ files needs to use assertf.h, just type #include "assertf.h".

  4. If you want to disable assertf.h on release build, please specify -DASSERTF_DISABLE in Makefile, CMakeLists.txt, etc.

API

Nearly all assertf.h APIs prefixed with assert, the most basic API is the

  • assertf(expr, fmt, ...)

    When expr isn't true, it'll print out a message backed by fmt and ... to stderr and then crash the whole program(if assertf.h is 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 a and b, fs is the format specifier of a, b will use the same format specifier as a, 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, fmt and ... 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_DISABLE in any part of your project source code, it'll break compilation semantics of assertf.h. Like aforementioned, define it in Makefile, CMakeLists.txt, etc.

  • Like #include <assert.h>, all assertf.h APIs isn't side-effect safe.

  • Like #include <assert.h>, when the expr not 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 the typeof with __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.h heavily and confidently in your code base.

  • Replace #include <assert.h> with #include "assertf.h". 😌

FAQ

  • HOWTO check if assertf.h disabled on a certain build?

    • UNIX-like systems

      $ nm some_binary | grep assertf
      0000000000007709 T x_assertf_c21162d2

      If you see x_assertf_c21162d2, it means assertf.h is enabled in some_binary.

      Note that if you strip(1) the symbols, you have no way to determine whether assertf.h disabled or not.

    • Windows

      You need have to check the pdb(Program database) file.

Releases

No releases published

Packages

No packages published

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /