From 1ebe949507b48a6b62dd36e08f0ae80da2ee1dcc Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Fri, 5 Sep 2025 20:47:48 +0000 Subject: [PATCH] 8314488: Compiling the JDK with C++17 Reviewed-by: dholmes, stefank, ayang, kvn, iwalulya, jsjolen, ihse --- doc/hotspot-style.html | 617 ++++++++++++++++-- doc/hotspot-style.md | 606 ++++++++++++++++- make/autoconf/flags-cflags.m4 | 6 +- .../vscode/hotspot/indexers/ccls-settings.txt | 2 +- .../hotspot/indexers/clangd-settings.txt | 2 +- .../hotspot/indexers/cpptools-settings.txt | 2 +- .../hotspot/indexers/rtags-settings.txt | 2 +- 7 files changed, 1150 insertions(+), 87 deletions(-) diff --git a/doc/hotspot-style.html b/doc/hotspot-style.html index 88ec07475fd..98d813242a5 100644 --- a/doc/hotspot-style.html +++ b/doc/hotspot-style.html @@ -50,6 +50,9 @@ id="toc-factoring-and-class-design">Factoring and Class Design
  • Commenting
  • Macros
  • Whitespace
  • +
  • Avoid implicit conversions +to bool
  • Miscellaneous
  • @@ -72,28 +75,74 @@ Standard Library Deduction
  • Expression SFINAE
  • +
  • Non-type template parameter +values
  • enum
  • alignas
  • thread_local
  • nullptr
  • <atomic>
  • +
  • Inline +Variables
  • Initializing variables with static storage duration
  • Uniform Initialization
  • +
  • Mandatory Copy Elision
  • Local Function Objects
  • Inheriting constructors
  • Attributes
  • noexcept
  • +
  • Enhanced selection +statements
  • +
  • Expression Evaluation +Order
  • +
  • Compatibility with C11
  • Additional Permitted Features
  • +
  • Excluded +Features +
  • Undecided +Features +
  • @@ -418,22 +467,25 @@ adjust new lines horizontally to be consistent with that organization. (E.g., trailing backslashes on long macro definitions often align.)

    -

    Miscellaneous

    - +

    Miscellaneous

    +

    Use of C++ Features

    HotSpot was originally written in a subset of the C++98/03 language. -More recently, support for C++14 is provided, though again, HotSpot only +More recently, support for C++17 is provided, though again, HotSpot only uses a subset. (Backports to JDK versions lacking support for more recent Standards must of course stick with the original C++98/03 subset.)

    This section describes that subset. Features from the C++98/03 language may be used unless explicitly excluded here. Features from -C++11 and C++14 may be explicitly permitted or explicitly excluded, and -discussed accordingly here. There is a third category, undecided -features, about which HotSpot developers have not yet reached a -consensus, or perhaps have not discussed at all. Use of these features +C++11, C++14, and C++17 may be explicitly permitted or explicitly +excluded, and discussed accordingly here. There is a third category, +undecided features, about which HotSpot developers have not yet reached +a consensus, or perhaps have not discussed at all. Use of these features is also excluded.

    (The use of some features may not be immediately obvious and may slip in anyway, since the compiler will accept them. The code review process @@ -463,9 +515,9 @@ is the main defense against this.)

    provide more extensive discussion or rationale for limitations. Features that don't have their own subsection are listed in omnibus feature sections for permitted, excluded, and undecided features.

    -

    Lists of new features for C++11 and C++14, along with links to their -descriptions, can be found in the online documentation for some of the -compilers and libraries. The C++14 Standard is the definitive +

    Lists of new features for C++11, C++14, and C++17, along with links +to their descriptions, can be found in the online documentation for some +of the compilers and libraries. The C++17 Standard is the definitive description.

    +
      ScopeGuard guard{[&]{ ... cleanup code ... }};
    +

    Expression SFINAE

    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95468
    https://developercommunity.visualstudio.com/content/problem/396562/sizeof-deduced-type-is-sometimes-not-a-constant-ex.html

    +

    Non-type template parameter +values

    +

    C++17 extended the arguments permitted for non-type template +parameters (n4268). The kinds of +values (the parameter types) aren't changed. However, the values can now +be the result of arbitrary constant expressions (with a few restrictions +on the result), rather than a much more limited and restrictive set of +expressions. In particular, the argument for a pointer or reference type +parameter can now be the result of a constexpr function.

    enum

    Where appropriate, scoped-enums should be used. (n2347)

    @@ -805,6 +893,34 @@ differ from what the Java compilers implement.

    "conservative" memory ordering, which may differ from (may be stronger than) sequentially consistent. There are algorithms in HotSpot that are believed to rely on that ordering.

    +

    Inline Variables

    +

    Variables with static storage duration may be declared +inline (p0386r2). +This has similar effects as for declaring a function inline: it can be +defined, identically, in multiple translation units, must be defined in +every translation unit in which it is ODR used, and the behavior of the +program is as if there is exactly one variable.

    +

    Declaring a variable inline allows the complete definition to be in a +header file, rather than having a declaration in a header and the +definition in a .cpp file. The guidance on initialization +of such variables still applies. Inline variables with dynamic +initializations can make initialization order problems worse. The few +ordering constraints that exist for non-inline variables don't apply, as +there isn't a single program-designated translation unit containing the +definition.

    +

    A constexpr static data member is implicitly +inline. As a consequence, an ODR use of such a variable doesn't +require a definition in some .cpp file. (This is a change from +pre-C++17. Beginning with C++17, such a definition is considered a +duplicate definition, and is deprecated.)

    +

    Declaring a thread_local variable inline is +forbidden for HotSpot code. The use of +thread_local is already heavily restricted.

    Initializing variables with static storage duration

    @@ -856,6 +972,45 @@ initialization

    Although related, the use of std::initializer_list remains forbidden, as part of the avoidance of the C++ Standard Library in HotSpot code.

    +

    Mandatory Copy Elision

    +

    Copy elision +(or here) +is a compiler optimization used to avoid potentially expensive copies in +certain situations. It is critical to making practical the performance +of return by value or pass by value. It is also unusual in not following +the as-if rule for optimizations - copy elision can be applied even if +doing so bypasses side-effects of copying/moving the object. The C++ +standard explicitly permits this.

    +

    However, because it's an optional optimization, the relevant +copy/move constructor must be available and accessible, in case the +compiler chooses to not apply the optimization even in a situation where +permitted.

    +

    C++17 changed some cases of copy elision so that there is never a +copy/move in these cases (p0135r1). The interesting cases +involve a function that returns an unnamed temporary object, and +constructors. In such cases the object being initialized from the +temporary is always direct initialized, with no copy/move ever involved; +see RVO and more specifically URVO.

    +

    Since this is now standard behavior it can't be avoided in the +covered situations. This could change the behavior of code that relied +on side effects by constructors, but that's both uncommon and was +already problematic because of the previous optional copy elision. But +HotSpot code can, and should, explicitly take advantage of this newly +required behavior where it makes sense to do so.

    +

    For example, it may be beneficial to delay construction of the result +of a function until the return statement, rather than having a local +variable that is modified into the desired state and then returned. +(Though NRVO may apply in that +case.)

    +

    It is also now possible to define a factory function for a class that +is neither movable nor copyable, if it can be written in a way that +makes use of this feature.

    Local Function Objects

    +
  • By-value capture of this (using a capture list like +[*this] (p0018r3)) +is also not permitted. One of the motivating use-cases is when the +lifetime of the lambda exceeds the lifetime of the object for the +containing member function. That is, we have an upward lambda that is +capturing this of the enclosing method. But again, that +use-case doesn't apply if only downward lambdas are used. Another +use-case is when we simply want the lambda to be operating on a copy of +this for some reason. This is sufficiently uncommon that it +can be handled by manual copying, so readers don't need to understand +this rare syntax.

  • Non-capturing lambdas (with an empty capture list - []) have limited utility. There are cases where no captures are required (pure functions, for example), but if the function is small @@ -984,14 +1158,15 @@ href="https://isocpp.org/files/papers/N3649.html">N3649) are not permitted. Capture initializers inherently increase the complexity of the capture list, and provide little benefit over an additional in-scope local variable.

  • - -

    The use of mutable lambda expressions is forbidden +

  • The use of mutable lambda expressions is forbidden because there don't seem to be many, if any, good use-cases for them in HotSpot. A lambda expression needs to be mutable in order to modify a by-value captured value. But with only downward lambdas, such usage seems likely to be rare and complicated. It is better to use a function object class in any such cases that arise, rather than requiring all -HotSpot developers to understand this relatively obscure feature.

    +HotSpot developers to understand this relatively obscure +feature.

  • +

    While it is possible to directly invoke an anonymous lambda expression, that feature should not be used, as such a form can be confusing to readers. Instead, name the lambda and call it by name.

    @@ -1109,23 +1284,12 @@ href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm">n2540C++11 provides simple syntax allowing a class to inherit the constructors of a base class. Unfortunately there are a number of problems with the original specification, and C++17 contains significant -revisions (p0136r1 opens with a list of 8 Core Issues). Since -HotSpot doesn't support use of C++17, use of inherited constructors -could run into those problems. Such uses might also change behavior in a -future HotSpot update to use C++17 or later, potentially in subtle ways -that could lead to hard to diagnose problems. Because of this, HotSpot -code must not use inherited constructors.

    -

    Note that gcc7 provides the -fnew-inheriting-ctors -option to use the p0136r1 semantics. This is enabled by default when -using C++17 or later. It is also enabled by default for -fabi-version=11 (introduced by gcc7) or higher when using -C++11/14, as the change is considered a Defect Report that applies to -those versions. Earlier versions of gcc don't have that option, and -other supported compilers may not have anything similar.

    +revisions (p0136r1 +opens with a list of 8 Core Issues). Although those issues have been +addressed, the benefits from this feature are small compared to the +complexity. Because of this, HotSpot code must not use inherited +constructors.

    +

    p0195r0

    Attributes

    The use of some attributes (n2761) @@ -1141,9 +1305,17 @@ those cases HotSpot has a preferred location.

    beginning of the function's declaration, rather than between the function name and the parameter list. +

    p0068r0 is the initial +proposal for the attributes added by C++17.)

    Only the following attributes are permitted:

    The following attributes are expressly forbidden:

    +

    Direct use of non-standard (and presumably scoped) attributes in +shared code is also forbidden. Using such would depend on the C++17 +feature that an attribute not recognized by the implementation is +ignored (p0283r2). If such an +attribute is needed in shared code, the well-established technique of +providing an ATTRIBUTE_XXX macro with per-compiler +definitions (sometimes empty) should be used. Compilers may warn about +unrecognized attributes (whether by name or by location), in order to +report typos or misuse. Disabling such warnings globally would not be +desirable.

    +

    The use of using directives in attribute lists is also +forbidden. (p0028r0) (p0028r4) We don't generally use +scoped attributes in attribute lists with other attributes. Rather, uses +of scoped attributes (which are implementation defined) are generally +hidden behind a portability macro that includes the surrounding +brackets.

    noexcept

    Use of noexcept exception specifications (n3050) are permitted with restrictions @@ -1200,9 +1389,72 @@ Standard Library facilities.

    functions not declared noexcept. So HotSpot code doesn't ever need to check, either with conditional exception specifications or with noexcept expressions.

    +

    The exception specification is part of the type of a function (p0012r1. This likely has little +impact on HotSpot code, since the use of noexcept is +expected to be rare.

    Dynamic exception specifications were deprecated in C++11. C++17 removed all but throw(), with that remaining a deprecated equivalent to noexcept.

    +

    Enhanced selection +statements

    +

    C++17 modified the condition part of if and +switch statements, permitting an init-statement to +be included (p0305r1).

    +

    Use of this feature is permitted. (However, complex uses may +interfere with readability.) Limiting the scope of a variable involved +in the condition, while also making the value available to the +statement's body, can improve readability. The alternative method of +scope-limiting by introducing a nested scope isn't very popular and is +rarely used.

    +

    This new syntax is in addition to the condition being a +declaration with a brace-or-equal-initializer. For an +if statement this new sytax gains that benefit without +violating the long-standing guidance against using implicit conversions to +bool, which still stands.

    +

    For example, uses of Unified Logging sometimes explicitly check +whether a LogTarget is enabled. Instead of

    +
      LogTarget(...) lt;
    +  if (lt.is_enabled()) {
    +    LogStream log(lt);
    +    ... use log ...
    +  }
    +  ... lt is accessible but probably not needed here ...
    +

    using this feature one could write

    +
      if (LogTarget(...) lt; lt.is_enabled()) {
    +    LogStream log(lt);
    +    ... use log ...
    +  }
    +

    C++17 also added compile-time if statements (p0292r2). Use of +if constexpr is permitted. This feature can replace and +(sometimes vastly) simplify many uses of SFINAE. The same +declaration and initialization guidance for the condition part +apply here as for ordinary if statements.

    +

    Expression Evaluation Order

    +

    C++17 tightened up the evaluation order for some kinds of +subexpressions (p0138r2). Note, +however, that the Alternate Evaluation Order for Function Calls +alternative in that paper was adopted, rather than the strict left to +right order of evaluation for function call arguments that was proposed +in the main body of the paper.

    +

    The primary purpose of this change seems to be to make certain kinds +of call chaining well defined. That's not a style widely used in +HotSpot. In general it is better to continue to avoid questions in this +area by isolating operations with side effects from other statements. In +particular, continue to avoid modifying a value in an expression where +it is also used.

    +

    Compatibility with C11

    +

    C++17 refers to C11 rather than C99. This means that C11 libraries +and functions may be used in HotSpot. There may be limitations because +of differing levels of compatibility among various compilers and +versions of those compilers.

    +

    Note that the C parts of the JDK have been built with C11 selected +for some time (JDK-8292008).

    Additional Permitted Features

    -

    Excluded Features

    +

    Excluded Features

    +

    Structured Bindings

    +

    The use of structured bindings p0217r3 is forbidden. Preferred +approaches for handling functions with multiple return values +include

    + +

    There is a strong preference for names and explicit types, as opposed +to offsets and implicit types. For example, there are folks who strongly +dislike that some of the Standard Library functions return +std::pair because first and +second members don't carry any useful information.

    +

    File System Library

    +

    The use of the File System library is forbidden. HotSpot doesn't do +very much with files, and already has adequate mechanisms for its needs. +Rewriting in terms of this new library doesn't provide any obviously +significant benefits. Having a mix of the existing usage and uses of +this new library would be confusing.

    +

    n4100 p0218r0 p0219r1 p0317r1 p0392r0 p0430r2 p0492r2 p1164r1

    +

    Aggregate Extensions

    +

    Aggregates with base classes are forbidden. C++17 allows aggregate +initialization for classes with base classes (p0017r1). HotSpot makes very little +use of aggregate classes, preferring explicit constructors even for very +simple classes.

    +

    Additional Excluded Features