RFR: 8377895: Create sizeof_auto, to reduce narrowing conversions [v2]
Kim Barrett
kbarrett at openjdk.org
Tue Feb 17 17:25:35 UTC 2026
On Tue, 17 Feb 2026 14:15:42 GMT, Kim Barrett <kbarrett at openjdk.org> wrote:
>> src/hotspot/share/utilities/globalDefinitions.hpp line 186:
>>
>>> 184: // Use this instead of sizeof() if you want your expression not to be of type size_t
>>> 185: template <typename T>
>>> 186: constexpr auto sizeof_auto(const T& t) {
>>
>> I think this should be a macro, so it can avoid evaluating the argument, a la `sizeof`.
>> Expansion would use `decltype` of the argument.
>> This would either require different naming from the no-arg case, or doing macro overloading
>> on the number of arguments. (I kind of remember tricks for doing that, but it's "hard" to
>> distinguish zero from non-zero. And we don't have `__VA_OPT__` until C++20. Maybe
>> there are non-portable solutions for that?)
>
> Oh, but we don't need to worry about variadic macros here. `sizeof_auto<T>()` can't
> be a function-like macro invocation. So something like this (not tested) should work:
>
> #define sizeof_auto(...) sizeof_auto<decltype(__VA_ARGS__)>()
>
> It's a variadic macro so that we don't need to parenthesize an expression containing
> unparenthesized commas (like a template argument list).
>
> A different syntactic option would be a macro for both cases, e.g. `sizeof_auto(X)`
> where `X` is either a type or an expression, just like `sizeof`. I remember a trick for
> distinguishing between those, though would need to do some dredging to recall the
> details. But while it would be "fun" it might be considered a bit more effort than the
> nice and consistent syntax is worth. I might give it a try, just to see how hard it really is.
I remembered enough of the trick to think it probably doesn't work here. However, there's a variant, using C++17 features, that I think probably would work. But I didn't explore in that direction because I realized there's a *much* simpler approach; just use `sizeof` to deal with that dispatch. Here's my (untested, hopefully no syntax errors) solution:
template<size_t N>
constexpr auto sizeof_auto_impl() {
using unsigned_auto =
std::conditional_t<N <= std::numeric_limits<uint8_t>::max(), uint8_t,
std::conditional_t<N <= std::numeric_limits<uint16_t>::max(), uint16_t,
std::conditional_t<N <= std::numeric_limits<uint32_t>::max(), uint32_t, uint64_t>>>;
return static_cast<unsigned_auto>(N);
}
#define sizeof_auto(...) sizeof_auto_impl<sizeof(__VA_ARGS__)>()
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/29716#discussion_r2818162789
More information about the hotspot-dev
mailing list