8249945: Improve ARRAY_SIZE()

Make ARRAY_SIZE type-safe.

Reviewed-by: tschatzl, lfoltan, dholmes
This commit is contained in:
Kim Barrett 2020-07-24 05:07:37 -04:00
parent 26680f0c1a
commit 8b005fa74e
2 changed files with 32 additions and 1 deletions
src/hotspot/share/utilities
test/hotspot/gtest/utilities

@ -1095,7 +1095,11 @@ template<class T> static void swap(T& a, T& b) {
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

@ -223,3 +223,30 @@ TEST(globalDefinitions, log2) {
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");
}
}