[IOT-2268] cleanup unused-local-typedefs warning
authorGeorge Nash <george.nash@intel.com>
Tue, 25 Jul 2017 16:38:19 +0000 (09:38 -0700)
committerRick Bell <richard.s.bell@intel.com>
Mon, 18 Sep 2017 17:39:17 +0000 (17:39 +0000)
The definition used for the OC_STATIC_ASSERT created
an unused typedef with an array of an invalid size
if the assert condition was not met. This resulted
in an unused-local-typedef warning every time
OC_STATIC_ASSERT was used even if it did not cause
a static assert.

The macro was updated to create an enum of 1/condition
if the condition is false this will create a compiler
warning because 1/0 is an invalid value. Its supprisingly
difficult to find a macro that will satisfy C, and C++
for most standard compilers. With out producing a warning.

Also when possible the __COUNTER__ macro is used to create
the unique identifier for the OC_STATIC_ASSERT this
addresses the problem of using the static ASSERT on the
same line. This would have been an issue with the original
way the code was written.

Bug: https://jira.iotivity.org/browse/IOT-2268
Bug: https://jira.iotivity.org/browse/IOT-2539
Change-Id: I4a9cc8d61702eacaddfd1ae5679126af02208f5e
Signed-off-by: George Nash <george.nash@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/21619
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Rick Bell <richard.s.bell@intel.com>
(cherry picked from commit db426b113862fddd2241029dd8f7ee4bed01e39a)

resource/c_common/platform_features.h

index 3e6f0b018713dc6c176ba31a2f3223753d3c0198..2eb3abf3869797f39d2fcd999ebedd061852df7e 100644 (file)
 #else
 #  define OC_CAT_(a, b) a ## b
 #  define OC_CAT(a, b) OC_CAT_(a, b)
-#  define OC_STATIC_ASSERT(condition, msg) \
-        typedef int OC_CAT(StaticAssertTemp, __LINE__)[2 * !!(condition) - 1]
+/*
+ * __COUNTER__ Expands to an integer that starts at 0 an is incremented by 1 every
+ * time it is used in a source file.
+ * It is used here to create a unique identifier.
+ * It is supported in MSVC since at least VS2015 and gcc version 4.3.0
+ */
+#  ifdef __COUNTER__
+#    define OC_STATIC_ASSERT(condition, msg) \
+       { enum { OC_CAT(StaticAssert_, __COUNTER__) = 1/(int)(!!(condition)) }; }
+#  else
+     /*
+      * Note this can not be used twice on the same line. Make sure header guards
+      * (i.e #ifdef HEADER ... #endif) are used to avoid including twice.
+      */
+#    define OC_STATIC_ASSERT(condition, msg) \
+       { enum { OC_CAT(StaticAssert_line_, __LINE__) = 1/(int)(!!(condition)) }; }
+#  endif
 #endif
 
 #if !(defined _GLIBCXX_USE_NANOSLEEP) \