ctassert.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /* Copyright (c) 2018 The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file ctassert.h
  5. *
  6. * \brief Compile-time assertions: CTASSERT(expression).
  7. */
  8. #ifndef TOR_CTASSERT_H
  9. #define TOR_CTASSERT_H
  10. #include "lib/cc/compat_compiler.h"
  11. /**
  12. * CTASSERT(expression)
  13. *
  14. * Trigger a compiler error if expression is false.
  15. */
  16. #if __STDC_VERSION__ >= 201112L
  17. /* If C11 is available, just use _Static_assert. */
  18. #define CTASSERT(x) _Static_assert((x), #x)
  19. #else /* !(__STDC_VERSION__ >= 201112L) */
  20. /*
  21. * If C11 is not available, expand __COUNTER__, or __INCLUDE_LEVEL__
  22. * and __LINE__, or just __LINE__, with an intermediate preprocessor
  23. * macro CTASSERT_EXPN, and then use CTASSERT_DECL to paste the
  24. * expansions together into a unique name.
  25. *
  26. * We use this name as a typedef of an array type with a positive
  27. * length if the assertion is true, and a negative length of the
  28. * assertion is false, which is invalid and hence triggers a compiler
  29. * error.
  30. */
  31. #if defined(__COUNTER__)
  32. #define CTASSERT(x) CTASSERT_EXPN((x), c, __COUNTER__)
  33. #elif defined(__INCLUDE_LEVEL__)
  34. #define CTASSERT(x) CTASSERT_EXPN((x), __INCLUDE_LEVEL__, __LINE__)
  35. #else
  36. /* hope it's unique enough */
  37. #define CTASSERT(x) CTASSERT_EXPN((x), l, __LINE__)
  38. #endif /* defined(__COUNTER__) || ... */
  39. #define CTASSERT_EXPN(x, a, b) CTASSERT_DECL(x, a, b)
  40. #define CTASSERT_DECL(x, a, b) \
  41. typedef char tor_ctassert_##a##_##b[(x) ? 1 : -1] ATTR_UNUSED
  42. #endif /* __STDC_VERSION__ >= 201112L */
  43. #endif /* !defined(TOR_CTASSERT_H) */