RFR: 8255082: HotSpot Style Guide should permit noexcept [v3]

Kim Barrett kbarrett at openjdk.org
Fri Jun 20 15:59:36 UTC 2025


On Fri, 20 Jun 2025 14:03:39 GMT, Vladimir Kozlov <kvn at openjdk.org> wrote:

>> Kim Barrett has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   more dholmes
>
> doc/hotspot-style.md line 1118:
> 
>> 1116: failure must be declared `noexcept`.
>> 1117: * All other uses of `noexcept` exception specifications are forbidden.
>> 1118: * `noexcept` expressions are forbidden.
> 
> "argument-less form of `noexcept` are permitted" vs "`noexcept` expressions are forbidden". So what we should use? `noexcept()`? The example would be nice.

The standard allows `noexcept` to be used in two different contexts. It can be
used in a function's exception specification. It can instead be used in an
ordinary expression. In either case it takes one argument expression, but what
form that can take and how it is interpreted is quite different, depending on
which of those contexts applies.

Used in an exception specification, the argument must be a constant
expression. So one can write a conditional exception specification, indicating
that a function is non-throwing if the argument is true, and potentially
throwing if false. One use-case for this is a generic container, where some
operations may only be noexept if certain operations of the element type are
noexcept. In this context, `noexcept` (without arguments) is equivalent to
`noexcept(true)`, and also to the deprecated `throw()` (with no arguments). At
this time I think we don't ever need arguments, and the no-arg abbreviation is
sufficient. That might change if we move toward using standard library
facilities (particularly containers), or make our own more like those in the
standard.

Used as an expression, the argument is an unevaluated expression (similar to
some uses of sizeof and alignof). The result of the `noexcept` expression is a
bool constant, and is true if the expression never throws (based on examining
exception specifications of functions called in the expression), false
otherwise. There isn't an abbreviated expression form without arguments, as
that doesn't make sense. At this time I think we don't need `noexcept`
expressions, and might never need them.

(Note that the argument expression for a `noexcept` exception specification
can include `noexcept` expressions. But since we're not currently allowing
either, that doesn't matter.)

> doc/hotspot-style.md line 1140:
> 
>> 1138: result. If an allocation function is not declared `noexcept` then the compiler
>> 1139: may elide that checking and handling for a `new` expression calling that
>> 1140: function.
> 
> This implies that compiler may generate a `nullptr` check if `noexcept` is specified.  Is it true?  Is it static (during compilation) check or it can generate runtime check?
> 
> We usually have explicit checks in such places to catch allocation failure. We are missing check in some places which may lead to crashes (reference through `nullptr`). Can compiler helps here?

An allocation function may be declared as non-throwing (via `noexcept`).

If not declared non-throwing (so "potentially throwing", even though in a
no-exceptions build environment it won't ever actually throw, and will instead
probably terminate the program), the compiler's implementation of a using
`new` expression can assume the allocation function will never return null,
and does not need to generate any code to handle that possibility.

If declared non-throwing, a using `new` expression must account for the
possibility that the allocation function might return null. It needs to test
the result of the allocation function. If it is null then the `new` expression
must not call the constructor for the type and must return null as its result.
(Of course, usual compiler optimizations apply, and the null handling code can
be elided if the compiler can prove the allocation does not in fact ever
return null, regardless of any exception specifications. That's probably
pretty much never the case though.)

Because of that, an allocation function that can return null *must* be
declared non-throwing. And an allocation function that never returns null
shouldn't be declared non-throwing, as that's just degrading performance for
no reason.

> doc/hotspot-style.md line 1153:
> 
>> 1151: HotSpot code can assume no exceptions will ever be thrown, even from functions
>> 1152: not declared `noexcept`. So HotSpot code doesn't ever need to check, either
>> 1153: with conditional exception specifications or with `noexcept` expressions.
> 
> "doesn't ever need to check" - what check? We still need to have nullptr checks. Right?

If a `new` expression is calling a non-throwing variant then the caller of the
`new` expression should be handling the possible null result. An assert is
generally not the appropriate "handling". If one isn't prepared to handle a
null result then don't call the variant that might return that.

In our typical usage, if calling a potentially throwing variant, it will never
return null, instead terminating the program. In such a case, there's no need
for a null check by the caller, as we know that case is handled inside the
call.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/25574#discussion_r2159297650
PR Review Comment: https://git.openjdk.org/jdk/pull/25574#discussion_r2159297774
PR Review Comment: https://git.openjdk.org/jdk/pull/25574#discussion_r2159297894


More information about the hotspot-dev mailing list