changeset 60299:7f4d7d34b92d

8249945: Improve ARRAY_SIZE() Summary: Make ARRAY_SIZE type-safe. Reviewed-by: tschatzl, lfoltan, dholmes
author kbarrett
date Fri, 24 Jul 2020 05:07:37 -0400
parents 8b8111739fed
children a36b9f6adbf2 881e79dd6152
files src/hotspot/share/utilities/globalDefinitions.hpp test/hotspot/gtest/utilities/test_globalDefinitions.cpp
diffstat 2 files changed, 32 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/utilities/globalDefinitions.hpp	Fri Jul 24 11:16:08 2020 +0200
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp	Fri Jul 24 05:07:37 2020 -0400
@@ -1095,7 +1095,11 @@
   b = tmp;
 }
 
-#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
+// array_size_impl is a function that takes a reference to T[N] and
+// returns a reference to char[N].  It is not ODR-used, so not defined.
+template<typename T, size_t N> char (&array_size_impl(T (&)[N]))[N];
+
+#define ARRAY_SIZE(array) sizeof(array_size_impl(array))
 
 //----------------------------------------------------------------------------------------------------
 // Sum and product which can never overflow: they wrap, just like the
--- a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp	Fri Jul 24 11:16:08 2020 +0200
+++ b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp	Fri Jul 24 05:07:37 2020 -0400
@@ -223,3 +223,30 @@
   EXPECT_EQ_LOG2(log2_uint, uint);
   EXPECT_EQ_LOG2(log2_jlong, jlong);
 }
+
+TEST(globalDefinitions, array_size) {
+  const size_t test_size = 10;
+
+  {
+    int test_array[test_size] = {};
+    static_assert(test_size == ARRAY_SIZE(test_array), "must be");
+  }
+
+  {
+    double test_array[test_size] = {};
+    static_assert(test_size == ARRAY_SIZE(test_array), "must be");
+  }
+
+  struct ArrayElt { int x; };
+
+  {
+    ArrayElt test_array[test_size] = {};
+    static_assert(test_size == ARRAY_SIZE(test_array), "must be");
+  }
+
+  {
+    const ArrayElt test_array[] = { {0}, {1}, {2}, {3}, {4}, {5} };
+    static_assert(6 == ARRAY_SIZE(test_array), "must be");
+  }
+
+}