summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2016-11-01 19:36:15 +0100
committerHaru <haru@dotalux.com>2016-12-03 15:38:54 +0100
commit9ac2545d66e630cce6a718a7c6f374fbecb00e96 (patch)
treef072dd57252447eee4d7d49a25692a0cd80350c1 /src
parent17420ee563282ba1791a77c55ede9d8f5f504ae5 (diff)
downloadhercules-9ac2545d66e630cce6a718a7c6f374fbecb00e96.tar.gz
hercules-9ac2545d66e630cce6a718a7c6f374fbecb00e96.tar.bz2
hercules-9ac2545d66e630cce6a718a7c6f374fbecb00e96.tar.xz
hercules-9ac2545d66e630cce6a718a7c6f374fbecb00e96.zip
Add support for static assertions (on compilers that support them)
This introduces the macro `STATIC_ASSERT(ex, msg)`, that works like its C11 counterpart `_Static_assert(ex, msg)`, on compilers that support it. Support is provided, depending on the compiler: - When in C11 mode, use the native `_Static_assert` - If the compiler advertises having the `c_static_assert` feature, use `_Static_assert` (according to the clang documentation). - If the compiler is GCC >= 4.7 (tested to be compatible), use `_Static_assert` (nonstandard extension, C11 feature available in C99). - If the compiler is MSVC (all the currently supported versions have been tested to be compatible), then use `static_assert` (nonstandard extension, C++ feature) - Otherwise, define it as a no-op macro. Signed-off-by: Haru <haru@dotalux.com>
Diffstat (limited to 'src')
-rw-r--r--src/common/cbasetypes.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h
index 8c3b5ad04..2c36c23bc 100644
--- a/src/common/cbasetypes.h
+++ b/src/common/cbasetypes.h
@@ -109,6 +109,14 @@
# define __attribute__(x)
#endif
+/// Feature/extension checking macros
+#ifndef __has_extension /* Available in clang and gcc >= 3 */
+#define __has_extension(x) 0
+#endif
+#ifndef __has_feature /* Available in clang and gcc >= 5 */
+#define __has_feature(x) __has_extension(x)
+#endif
+
//////////////////////////////////////////////////////////////////////////
// portable printf/scanf format macros and integer definitions
// NOTE: Visual C++ uses <inttypes.h> and <stdint.h> provided in /3rdparty
@@ -441,4 +449,23 @@ typedef char bool;
/** Support macros for marking structs as unavailable */
#define UNAVAILABLE_STRUCT int8 HERC__unavailable_struct
+/** Static assertion (only on compilers that support it) */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+// C11 version
+#define STATIC_ASSERT(ex, msg) _Static_assert(ex, msg)
+#elif __has_feature(c_static_assert)
+// Clang support (as per http://clang.llvm.org/docs/LanguageExtensions.html)
+#define STATIC_ASSERT(ex, msg) _Static_assert(ex, msg)
+#elif defined(__GNUC__) && GCC_VERSION >= 40700
+// GCC >= 4.7 is known to support it
+#define STATIC_ASSERT(ex, msg) _Static_assert(ex, msg)
+#elif defined(_MSC_VER)
+// MSVC doesn't support it, but it accepts the C++ style version
+#define STATIC_ASSERT(ex, msg) static_assert(ex, msg)
+#else
+// Otherise just ignore it until it's supported
+#define STATIC_ASSERT(ex, msg)
+#endif
+
+
#endif /* COMMON_CBASETYPES_H */