Browse Source

Fix #1180 ensure enums are 32bit integers

If that's not the case, the error during compile time will be similar to
`error: named bit-field 'static_assertion_failed_enum_must_be_32bit' has zero width`
Stefan Profanter 7 years ago
parent
commit
b9346bac3d
2 changed files with 31 additions and 1 deletions
  1. 30 0
      include/ua_config.h.in
  2. 1 1
      tools/generate_datatypes.py

+ 30 - 0
include/ua_config.h.in

@@ -277,6 +277,36 @@ extern "C" {
 # define UA_BINARY_OVERLAYABLE_FLOAT 0
 #endif
 
+/**
+ * Utility Definitions
+ * ^^^^^^^^^^^^^^^^^^^ */
+/* Outputs an error message at compile time if the assert fails.
+ * Example usage:
+ * UA_STATIC_ASSERT(sizeof(long)==7, use_another_compiler_luke)
+ * See: https://stackoverflow.com/a/4815532/869402 */
+#if defined(__cplusplus) && __cplusplus >= 201103L /* C++11 or above */
+# define UA_STATIC_ASSERT(cond,msg) static_assert(cond, #msg)
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L /* C11 or above */
+# define UA_STATIC_ASSERT(cond,msg) _Static_assert(cond, #msg)
+#elif defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) /* GCC, Clang, MSC */
+# define UA_CTASTR2(pre,post) pre ## post
+# define UA_CTASTR(pre,post) UA_CTASTR2(pre,post)
+# define UA_STATIC_ASSERT(cond,msg)                             \
+    typedef struct {                                            \
+        int UA_CTASTR(static_assertion_failed_,msg) : !!(cond); \
+    } UA_CTASTR(static_assertion_failed_,__COUNTER__)
+#else /* Everybody else */
+# define UA_STATIC_ASSERT(cond,msg) typedef char static_assertion_##msg[(cond)?1:-1]
+#endif
+
+/* To generate smaller binaries, descriptive strings can be excluded from the
+ * datatype description */
+#ifdef UA_ENABLE_TYPENAMES
+# define UA_TYPENAME(name) name,
+#else
+# define UA_TYPENAME(name)
+#endif
+
 #ifdef __cplusplus
 } // extern "C"
 #endif

+ 1 - 1
tools/generate_datatypes.py

@@ -191,7 +191,7 @@ class EnumerationType(Type):
         else:
             values = self.elements.items()
         return "typedef enum {\n    " + ",\n    ".join(map(lambda kv : "UA_" + self.name.upper() + "_" + kv[0].upper() + \
-                                                            " = " + kv[1], values)) + \
+                                                           " = " + kv[1], values)) + \
                ",\n    __UA_{0}_FORCE32BIT = 0x7fffffff\n".format(self.name.upper()) + "} " + \
                "UA_{0};\nUA_STATIC_ASSERT(sizeof(UA_{0}) == sizeof(UA_Int32), enum_must_be_32bit);".format(self.name)