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