diff options
author | Tom Lane | 2012-09-30 18:38:31 +0000 |
---|---|---|
committer | Tom Lane | 2012-09-30 18:38:31 +0000 |
commit | ea473fb2dee7dfe61f8fbdfac9d9da87d84e564e (patch) | |
tree | f54d9cb4b0200c7e81d07b942fbf384855db8297 /src/include/c.h | |
parent | 26fd82ddf1273d5df20b892fc02c8ca756d2e2bc (diff) |
Add infrastructure for compile-time assertions about variable types.
Currently, the macros only work with fairly recent gcc versions, but there
is room to expand them to other compilers that have comparable features.
Heavily revised and autoconfiscated version of a patch by Andres Freund.
Diffstat (limited to 'src/include/c.h')
-rw-r--r-- | src/include/c.h | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/include/c.h b/src/include/c.h index 50e1ecfde4d..06f689d3593 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -689,6 +689,47 @@ typedef NameData *Name; } while (0) +/* + * Macros to support compile-time assertion checks, if the compiler has them. + * + * If the "condition" (a compile-time-constant expression) evaluates to false, + * throw a compile error using the "errmessage" (a string literal). + * + * gcc 4.6 and up supports _Static_assert(), but it has bizarre syntactic + * placement restrictions. These macros make it safe to use as a statement + * or in an expression, respectively. + */ +#ifdef HAVE__STATIC_ASSERT +#define StaticAssertStmt(condition, errmessage) \ + do { _Static_assert(condition, errmessage); } while(0) +#define StaticAssertExpr(condition, errmessage) \ + ({ StaticAssertStmt(condition, errmessage); true; }) +#else /* !HAVE__STATIC_ASSERT */ +#define StaticAssertStmt(condition, errmessage) +#define StaticAssertExpr(condition, errmessage) ((void) true) +#endif /* HAVE__STATIC_ASSERT */ + + +/* + * Compile-time checks that a variable (or expression) has the specified type. + * + * AssertVariableIsOfType() can be used as a statement. + * AssertVariableIsOfTypeMacro() is intended for use in macros, eg + * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) + */ +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ +#define AssertVariableIsOfType(varname, typename) +#define AssertVariableIsOfTypeMacro(varname, typename) ((void) true) +#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ + + /* ---------------------------------------------------------------- * Section 7: random stuff * ---------------------------------------------------------------- |