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