# HG changeset patch # User kbarrett # Date 1420670762 18000 # Wed Jan 07 17:46:02 2015 -0500 # Node ID bd9d999c8fb1fd866c4fa19f3d3d8eb2d6aeaac1 # Parent e38b7790484aa7610d4483f8130d53ea8fb224b2 8067306: Improve STATIC_ASSERT Summary: New improved implementation Reviewed by: diff --git a/src/share/vm/utilities/debug.hpp b/src/share/vm/utilities/debug.hpp --- a/src/share/vm/utilities/debug.hpp +++ b/src/share/vm/utilities/debug.hpp @@ -225,21 +225,23 @@ void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2); -#ifdef ASSERT -// Compile-time asserts. -template struct StaticAssert; -template <> struct StaticAssert {}; +// Compile-time asserts. Cond must be a compile-time constant expression that +// is convertible to bool. STATIC_ASSERT() can be used anywhere a declaration +// may appear. +// +// Implementation Note: STATIC_ASSERT_FAILURE provides a value member +// rather than type member that could be used directly in the typedef, because +// a type member would require conditional use of "typename", depending on +// whether Cond is dependent or not. The use of a value member leads to the +// use of an array type. -// Only StaticAssert is defined, so if cond evaluates to false we get -// a compile time exception when trying to use StaticAssert. -#define STATIC_ASSERT(cond) \ - do { \ - StaticAssert<(cond)> DUMMY_STATIC_ASSERT; \ - (void)DUMMY_STATIC_ASSERT; /* ignore */ \ - } while (false) -#else -#define STATIC_ASSERT(cond) -#endif +template struct STATIC_ASSERT_FAILURE; +template<> struct STATIC_ASSERT_FAILURE { enum { value = 1 }; }; + +#define STATIC_ASSERT(Cond) \ + typedef char STATIC_ASSERT_FAILURE_ ## __LINE__ [ \ + STATIC_ASSERT_FAILURE< (Cond) ? true : false >::value ] \ + /* */ // out of shared space reporting enum SharedSpaceType {