jdk-24/doc/hotspot-style.html
2024-03-06 22:42:18 +00:00

1213 lines
63 KiB
HTML

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>HotSpot Coding Style</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
ul.task-list li input[type="checkbox"] {
width: 0.8em;
margin: 0 0.8em 0.2em -1.6em;
vertical-align: middle;
}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<header id="title-block-header">
<h1 class="title">HotSpot Coding Style</h1>
</header>
<nav id="TOC" role="doc-toc">
<ul>
<li><a href="#introduction" id="toc-introduction">Introduction</a>
<ul>
<li><a href="#why-care-about-style" id="toc-why-care-about-style">Why
Care About Style?</a></li>
<li><a href="#counterexamples-and-updates"
id="toc-counterexamples-and-updates">Counterexamples and
Updates</a></li>
</ul></li>
<li><a href="#structure-and-formatting"
id="toc-structure-and-formatting">Structure and Formatting</a>
<ul>
<li><a href="#factoring-and-class-design"
id="toc-factoring-and-class-design">Factoring and Class Design</a></li>
<li><a href="#source-files" id="toc-source-files">Source Files</a></li>
<li><a href="#jtreg-tests" id="toc-jtreg-tests">JTReg Tests</a></li>
<li><a href="#naming" id="toc-naming">Naming</a></li>
<li><a href="#commenting" id="toc-commenting">Commenting</a></li>
<li><a href="#macros" id="toc-macros">Macros</a></li>
<li><a href="#whitespace" id="toc-whitespace">Whitespace</a></li>
<li><a href="#miscellaneous"
id="toc-miscellaneous">Miscellaneous</a></li>
</ul></li>
<li><a href="#use-of-c-features" id="toc-use-of-c-features">Use of C++
Features</a>
<ul>
<li><a href="#error-handling" id="toc-error-handling">Error
Handling</a></li>
<li><a href="#rtti-runtime-type-information"
id="toc-rtti-runtime-type-information">RTTI (Runtime Type
Information)</a></li>
<li><a href="#memory-allocation" id="toc-memory-allocation">Memory
Allocation</a></li>
<li><a href="#class-inheritance" id="toc-class-inheritance">Class
Inheritance</a></li>
<li><a href="#namespaces" id="toc-namespaces">Namespaces</a></li>
<li><a href="#c-standard-library" id="toc-c-standard-library">C++
Standard Library</a></li>
<li><a href="#type-deduction" id="toc-type-deduction">Type
Deduction</a></li>
<li><a href="#expression-sfinae" id="toc-expression-sfinae">Expression
SFINAE</a></li>
<li><a href="#enum" id="toc-enum">enum</a></li>
<li><a href="#alignas" id="toc-alignas">alignas</a></li>
<li><a href="#thread_local" id="toc-thread_local">thread_local</a></li>
<li><a href="#nullptr" id="toc-nullptr">nullptr</a></li>
<li><a href="#atomic" id="toc-atomic">&lt;atomic&gt;</a></li>
<li><a href="#uniform-initialization"
id="toc-uniform-initialization">Uniform Initialization</a></li>
<li><a href="#local-function-objects"
id="toc-local-function-objects">Local Function Objects</a></li>
<li><a href="#inheriting-constructors"
id="toc-inheriting-constructors">Inheriting constructors</a></li>
<li><a href="#attributes" id="toc-attributes">Attributes</a></li>
<li><a href="#additional-permitted-features"
id="toc-additional-permitted-features">Additional Permitted
Features</a></li>
<li><a href="#excluded-features" id="toc-excluded-features">Excluded
Features</a></li>
<li><a href="#undecided-features" id="toc-undecided-features">Undecided
Features</a></li>
</ul></li>
</ul>
</nav>
<h2 id="introduction">Introduction</h2>
<p>This is a collection of rules, guidelines, and suggestions for
writing HotSpot code. Following these will help new code fit in with
existing HotSpot code, making it easier to read and maintain. Failure to
follow these guidelines may lead to discussion during code reviews, if
not outright rejection of a change.</p>
<h3 id="why-care-about-style">Why Care About Style?</h3>
<p>Some programmers seem to have lexers and even C preprocessors
installed directly behind their eyeballs. The rest of us require code
that is not only functionally correct but also easy to read. More than
that, since there is no one style for easy-to-read code, and since a
mashup of many styles is just as confusing as no style at all, it is
important for coders to be conscious of the many implicit stylistic
choices that historically have gone into the HotSpot code base.</p>
<p>Some of these guidelines are driven by the cross-platform
requirements for HotSpot. Shared code must work on a variety of
platforms, and may encounter deficiencies in some. Using platform
conditionalization in shared code is usually avoided, while shared code
is strongly preferred to multiple platform-dependent implementations, so
some language features may be recommended against.</p>
<p>Some of the guidelines here are relatively arbitrary choices among
equally plausible alternatives. The purpose of stating and enforcing
these rules is largely to provide a consistent look to the code. That
consistency makes the code more readable by avoiding non-functional
distractions from the interesting functionality.</p>
<p>When changing pre-existing code, it is reasonable to adjust it to
match these conventions. Exception: If the pre-existing code clearly
conforms locally to its own peculiar conventions, it is not worth
reformatting the whole thing. Also consider separating changes that make
extensive stylistic updates from those which make functional
changes.</p>
<h3 id="counterexamples-and-updates">Counterexamples and Updates</h3>
<p>Many of the guidelines mentioned here have (sometimes widespread)
counterexamples in the HotSpot code base. Finding a counterexample is
not sufficient justification for new code to follow the counterexample
as a precedent, since readers of your code will rightfully expect your
code to follow the greater bulk of precedents documented here.</p>
<p>Occasionally a guideline mentioned here may be just out of synch with
the actual HotSpot code base. If you find that a guideline is
consistently contradicted by a large number of counterexamples, please
bring it up for discussion and possible change. The architectural rule,
of course, is "When in Rome do as the Romans". Sometimes in the suburbs
of Rome the rules are a little different; these differences can be
pointed out here.</p>
<p>Proposed changes should be discussed on the <a
href="mailto:hotspot-dev@openjdk.org">HotSpot Developers</a> mailing
list. Changes are likely to be cautious and incremental, since HotSpot
coders have been using these guidelines for years.</p>
<p>Substantive changes are approved by <a
href="https://www.rfc-editor.org/rfc/rfc7282.html">rough consensus</a>
of the <a href="https://openjdk.org/census#hotspot">HotSpot Group</a>
Members. The Group Lead determines whether consensus has been
reached.</p>
<p>Editorial changes (changes that only affect the description of
HotSpot style, not its substance) do not require the full consensus
gathering process. The normal HotSpot pull request process may be used
for editorial changes, with the additional requirement that the
requisite reviewers are also HotSpot Group Members.</p>
<h2 id="structure-and-formatting">Structure and Formatting</h2>
<h3 id="factoring-and-class-design">Factoring and Class Design</h3>
<ul>
<li><p>Group related code together, so readers can concentrate on one
section of one file.</p></li>
<li><p>Classes are the primary code structuring mechanism. Place related
functionality in a class, or a set of related classes. Use of either
namespaces or public non-member functions is rare in HotSpot code.
Static non-member functions are not uncommon.</p></li>
<li><p>If a class <code>FooBar</code> is going to be used in more than
one place, put it a file named fooBar.hpp and fooBar.cpp. If the class
is a sidekick to a more important class <code>BazBat</code>, it can go
in bazBat.hpp.</p></li>
<li><p>Put a member function <code>FooBar::bang</code> into the same
file that defined <code>FooBar</code>, or its associated <em>.inline.hpp
or </em>.cpp file.</p></li>
<li><p>Use public accessor functions for member variables accessed
outside the class.</p></li>
<li><p>Assign names to constant literals and use the names
instead.</p></li>
<li><p>Keep functions small, a screenful at most. Split out chunks of
logic into file-local classes or static functions if needed.</p></li>
<li><p>Factor away nonessential complexity into local inline helper
functions and helper classes.</p></li>
<li><p>Think clearly about internal invariants that apply to each class,
and document them in the form of asserts within member
functions.</p></li>
<li><p>Make simple, self-evident contracts for member functions. If you
cannot communicate a simple contract, redesign the class.</p></li>
<li><p>Implement classes as if expecting rough usage by clients. Check
for incorrect usage of a class using <code>assert(...)</code>,
<code>guarantee(...)</code>, <code>ShouldNotReachHere()</code> and
comments wherever needed. Performance is almost never a reason to omit
asserts.</p></li>
<li><p>When possible, design as if for reusability. This forces a clear
design of the class's externals, and clean hiding of its
internals.</p></li>
<li><p>Initialize all variables and data structures to a known state. If
a class has a constructor, initialize it there.</p></li>
<li><p>Do no optimization before its time. Prove the need to
optimize.</p></li>
<li><p>When you must defactor to optimize, preserve as much structure as
possible. If you must hand-inline some name, label the local copy with
the original name.</p></li>
<li><p>If you need to use a hidden detail (e.g., a structure offset),
name it (as a constant or function) in the class that owns it.</p></li>
<li><p>Don't use the Copy and Paste keys to replicate more than a couple
lines of code. Name what you must repeat.</p></li>
<li><p>If a class needs a member function to change a user-visible
attribute, the change should be done with a "setter" accessor matched to
the simple "getter".</p></li>
</ul>
<h3 id="source-files">Source Files</h3>
<ul>
<li><p>All source files must have a globally unique basename. The build
system depends on this uniqueness.</p></li>
<li><p>Do not put non-trivial function implementations in .hpp files. If
the implementation depends on other .hpp files, put it in a .cpp or a
.inline.hpp file.</p></li>
<li><p>.inline.hpp files should only be included in .cpp or .inline.hpp
files.</p></li>
<li><p>All .inline.hpp files should include their corresponding .hpp
file as the first include line. Declarations needed by other files
should be put in the .hpp file, and not in the .inline.hpp file. This
rule exists to resolve problems with circular dependencies between
.inline.hpp files.</p></li>
<li><p>All .cpp files include precompiled.hpp as the first include
line.</p></li>
<li><p>precompiled.hpp is just a build time optimization, so don't rely
on it to resolve include problems.</p></li>
<li><p>Keep the include lines alphabetically sorted.</p></li>
<li><p>Put conditional inclusions (<code>#if ...</code>) at the end of
the include list.</p></li>
</ul>
<h3 id="jtreg-tests">JTReg Tests</h3>
<ul>
<li><p>JTReg tests should have meaningful names.</p></li>
<li><p>JTReg tests associated with specific bugs should be tagged with
the <code>@bug</code> keyword in the test description.</p></li>
<li><p>JTReg tests should be organized by component or feature under
<code>test/</code>, in a directory hierarchy that generally follows that
of the <code>src/</code> directory. There may be additional
subdirectories to further categorize tests by feature. This structure
makes it easy to run a collection of tests associated with a specific
feature by specifying the associated directory as the source of the
tests to run.</p>
<ul>
<li>Some (older) tests use the associated bug number in the directory
name, the test name, or both. That naming style should no longer be
used, with existing tests using that style being candidates for
migration.</li>
</ul></li>
</ul>
<h3 id="naming">Naming</h3>
<ul>
<li><p>The length of a name may be correlated to the size of its scope.
In particular, short names (even single letter names) may be fine in a
small scope, but are usually inappropriate for larger scopes.</p></li>
<li><p>Prefer whole words rather than abbreviations, unless the
abbreviation is more widely used than the long form in the code's
domain.</p></li>
<li><p>Choose names consistently. Do not introduce spurious variations.
Abbreviate corresponding terms to a consistent length.</p></li>
<li><p>Global names must be unique, to avoid <a
href="https://en.cppreference.com/w/cpp/language/definition"
title="One Definition Rule">One Definition Rule</a> (ODR) violations. A
common prefixing scheme for related global names is often used. (This is
instead of using namespaces, which are mostly avoided in
HotSpot.)</p></li>
<li><p>Don't give two names to the semantically same thing. But use
different names for semantically different things, even if they are
representationally the same. (So use meaningful <code>typedef</code> or
template alias names where appropriate.)</p></li>
<li><p>When choosing names, avoid categorical nouns like "variable",
"field", "parameter", "value", and verbs like "compute", "get".
(<code>storeValue(int param)</code> is bad.)</p></li>
<li><p>Type names and global names should use mixed-case with the first
letter of each word capitalized (<code>FooBar</code>).</p></li>
<li><p>Embedded abbreviations in otherwise mixed-case names are usually
capitalized entirely rather than being treated as a single word with
only the initial letter capitalized, e.g. "HTML" rather than
"Html".</p></li>
<li><p>Function and local variable names use lowercase with words
separated by a single underscore (<code>foo_bar</code>).</p></li>
<li><p>Class data member names have a leading underscore, and use
lowercase with words separated by a single underscore
(<code>_foo_bar</code>).</p></li>
<li><p>Constant names may be upper-case or mixed-case, according to
historical necessity. (Note: There are many examples of constants with
lowercase names.)</p></li>
<li><p>Constant names should follow an existing pattern, and must have a
distinct appearance from other names in related APIs.</p></li>
<li><p>Class and type names should be noun phrases. Consider an "er"
suffix for a class that represents an action.</p></li>
<li><p>Function names should be verb phrases that reflect changes of
state known to a class's user, or else noun phrases if they cause no
change of state visible to the class's user.</p></li>
<li><p>Getter accessor names are noun phrases, with no
"<code>get_</code>" noise word. Boolean getters can also begin with
"<code>is_</code>" or "<code>has_</code>". Member function for reading
data members usually have the same name as the data member, exclusive of
the leading underscore.</p></li>
<li><p>Setter accessor names prepend "<code>set_</code>" to the getter
name.</p></li>
<li><p>Other member function names are verb phrases, as if commands to
the receiver.</p></li>
<li><p>Avoid leading underscores (as "<code>_oop</code>") except in
cases required above. (Names with leading underscores can cause
portability problems.)</p></li>
</ul>
<h3 id="commenting">Commenting</h3>
<ul>
<li><p>Clearly comment subtle fixes.</p></li>
<li><p>Clearly comment tricky classes and functions.</p></li>
<li><p>If you have to choose between commenting code and writing wiki
content, comment the code. Link from the wiki to the source file if it
makes sense.</p></li>
<li><p>As a general rule don't add bug numbers to comments (they would
soon overwhelm the code). But if the bug report contains significant
information that can't reasonably be added as a comment, then refer to
the bug report.</p></li>
<li><p>Personal names are discouraged in the source code, which is a
team product.</p></li>
</ul>
<h3 id="macros">Macros</h3>
<ul>
<li><p>You can almost always use an inline function or class instead of
a macro. Use a macro only when you really need it.</p></li>
<li><p>Templates may be preferable to multi-line macros. (There may be
subtle performance effects with templates on some platforms; revert to
macros if absolutely necessary.)</p></li>
<li><p><code>#ifdef</code>s should not be used to introduce
platform-specific code into shared code (except for <code>_LP64</code>).
They must be used to manage header files, in the pattern found at the
top of every source file. They should be used mainly for major build
features, including <code>PRODUCT</code>, <code>ASSERT</code>,
<code>_LP64</code>, <code>INCLUDE_SERIALGC</code>,
<code>COMPILER1</code>, etc.</p></li>
<li><p>For build features such as <code>PRODUCT</code>, use
<code>#ifdef PRODUCT</code> for multiple-line inclusions or
exclusions.</p></li>
<li><p>For short inclusions or exclusions based on build features, use
macros like <code>PRODUCT_ONLY</code> and <code>NOT_PRODUCT</code>. But
avoid using them with multiple-line arguments, since debuggers do not
handle that well.</p></li>
<li><p>Use <code>CATCH</code>, <code>THROW</code>, etc. for
HotSpot-specific exception processing.</p></li>
</ul>
<h3 id="whitespace">Whitespace</h3>
<ul>
<li><p>In general, don't change whitespace unless it improves
readability or consistency. Gratuitous whitespace changes will make
integrations and backports more difficult.</p></li>
<li><p>Use <a
href="https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS)">One-True-Brace-Style</a>.
The opening brace for a function or class is normally at the end of the
line; it is sometimes moved to the beginning of the next line for
emphasis. Substatements are enclosed in braces, even if there is only a
single statement. Extremely simple one-line statements may drop braces
around a substatement.</p></li>
<li><p>Indentation levels are two columns.</p></li>
<li><p>There is no hard line length limit. That said, bear in mind that
excessively long lines can cause difficulties. Some people like to have
multiple side-by-side windows in their editors, and long lines may force
them to choose among unpleasant options. They can use wide windows,
reducing the number that can fit across the screen, and wasting a lot of
screen real estate because most lines are not that long. Alternatively,
they can have more windows across the screen, with long lines wrapping
(or worse, requiring scrolling to see in their entirety), which is
harder to read. Similar issues exist for side-by-side code
reviews.</p></li>
<li><p>Tabs are not allowed in code. Set your editor accordingly.<br>
(Emacs: <code>(setq-default indent-tabs-mode nil)</code>.)</p></li>
<li><p>Use good taste to break lines and align corresponding tokens on
adjacent lines.</p></li>
<li><p>Use spaces around operators, especially comparisons and
assignments. (Relaxable for boolean expressions and high-precedence
operators in classic math-style formulas.)</p></li>
<li><p>Put spaces on both sides of control flow keywords
<code>if</code>, <code>else</code>, <code>for</code>,
<code>switch</code>, etc. Don't add spaces around the associated
<em>control</em> expressions. Examples:</p>
<pre><code>while (test_foo(args...)) { // Yes
while(test_foo(args...)) { // No, missing space after while
while ( test_foo(args...) ) { // No, excess spaces around control</code></pre></li>
<li><p>Use extra parentheses in expressions whenever operator precedence
seems doubtful. Always use parentheses in shift/mask expressions
(<code>&lt;&lt;</code>, <code>&amp;</code>, <code>|</code>). Don't add
whitespace immediately inside parentheses.</p></li>
<li><p>Use more spaces and blank lines between larger constructs, such
as classes or function definitions.</p></li>
<li><p>If the surrounding code has any sort of vertical organization,
adjust new lines horizontally to be consistent with that organization.
(E.g., trailing backslashes on long macro definitions often
align.)</p></li>
</ul>
<h3 id="miscellaneous">Miscellaneous</h3>
<ul>
<li><p>Use the <a href="https://en.cppreference.com/w/cpp/language/raii"
title="Resource Acquisition Is Initialization">Resource Acquisition Is
Initialization</a> (RAII) design pattern to manage bracketed critical
sections. See class <code>ResourceMark</code> for an example.</p></li>
<li><p>Avoid implicit conversions to <code>bool</code>.</p>
<ul>
<li>Use <code>bool</code> for boolean values.</li>
<li>Do not use ints or pointers as (implicit) booleans with
<code>&amp;&amp;</code>, <code>||</code>, <code>if</code>,
<code>while</code>. Instead, compare explicitly, i.e.
<code>if (x != 0)</code> or <code>if (ptr != nullptr)</code>, etc.</li>
<li>Do not use declarations in <em>condition</em> forms, i.e. don't use
<code>if (T v = value) { ... }</code>.</li>
</ul></li>
<li><p>Use functions from globalDefinitions.hpp and related files when
performing bitwise operations on integers. Do not code directly as C
operators, unless they are extremely simple. (Examples:
<code>align_up</code>, <code>is_power_of_2</code>,
<code>exact_log2</code>.)</p></li>
<li><p>Use arrays with abstractions supporting range checks.</p></li>
<li><p>Always enumerate all cases in a switch statement or provide a
default case. It is ok to have an empty default with comment.</p></li>
</ul>
<h2 id="use-of-c-features">Use of C++ Features</h2>
<p>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
uses a subset. (Backports to JDK versions lacking support for more
recent Standards must of course stick with the original C++98/03
subset.)</p>
<p>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
is also excluded.</p>
<p>(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
is the main defense against this.)</p>
<p>Some features are discussed in their own subsection, typically to
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.</p>
<p>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
description.</p>
<ul>
<li><a href="https://gcc.gnu.org/projects/cxx-status.html">C++ Standards
Support in GCC</a></li>
<li><a href="https://clang.llvm.org/cxx_status.html">C++ Support in
Clang</a></li>
<li><a
href="https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance">Visual
C++ Language Conformance</a></li>
<li><a
href="https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html">libstdc++
Status</a></li>
<li><a href="https://libcxx.llvm.org/cxx1y_status.html">libc++
Status</a></li>
</ul>
<p>As a rule of thumb, permitting features which simplify writing code
and, especially, reading code, is encouraged.</p>
<p>Similar discussions for some other projects:</p>
<ul>
<li><p><a
href="https://google.github.io/styleguide/cppguide.html">Google C++
Style Guide</a> — Currently (2020) targeting C++17.</p></li>
<li><p><a
href="https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-features.md">C++11
and C++14 use in Chromium</a> — Categorizes features as allowed, banned,
or to be discussed.</p></li>
<li><p><a href="https://llvm.org/docs/CodingStandards.html">llvm Coding
Standards</a> — Currently (2020) targeting C++14.</p></li>
<li><p><a
href="https://firefox-source-docs.mozilla.org/code-quality/coding-style/using_cxx_in_firefox_code.html">Using
C++ in Mozilla code</a> — C++17 support is required for recent versions
(2020).</p></li>
</ul>
<h3 id="error-handling">Error Handling</h3>
<p>Do not use exceptions. Exceptions are disabled by the build
configuration for some platforms.</p>
<p>Rationale: There is significant concern over the performance cost of
exceptions and their usage model and implications for maintainable code.
That's not just a matter of history that has been fixed; there remain
questions and problems even today (2019). See, for example, <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf">Zero
cost deterministic exceptions</a>. Because of this, HotSpot has always
used a build configuration that disables exceptions where that is
available. As a result, HotSpot code uses error handling mechanisms such
as two-phase construction, factory functions, returning error codes, and
immediate termination. Even if the cost of exceptions were not a
concern, the existing body of code was not written with exception safety
in mind. Making HotSpot exception safe would be a very large
undertaking.</p>
<p>In addition to the usual alternatives to exceptions, HotSpot provides
its own exception mechanism. This is based on a set of macros defined in
utilities/exceptions.hpp.</p>
<h3 id="rtti-runtime-type-information">RTTI (Runtime Type
Information)</h3>
<p>Do not use <a
href="https://en.wikipedia.org/wiki/Run-time_type_information"
title="Runtime Type Information">Runtime Type Information</a> (RTTI). <a
href="https://en.wikipedia.org/wiki/Run-time_type_information"
title="Runtime Type Information">RTTI</a> is disabled by the build
configuration for some platforms. Among other things, this means
<code>dynamic_cast</code> cannot be used.</p>
<p>Rationale: Other than to implement exceptions (which HotSpot doesn't
use), most potential uses of <a
href="https://en.wikipedia.org/wiki/Run-time_type_information"
title="Runtime Type Information">RTTI</a> are better done via virtual
functions. Some of the remainder can be replaced by bespoke mechanisms.
The cost of the additional runtime data structures needed to support <a
href="https://en.wikipedia.org/wiki/Run-time_type_information"
title="Runtime Type Information">RTTI</a> are deemed not worthwhile,
given the alternatives.</p>
<h3 id="memory-allocation">Memory Allocation</h3>
<p>Do not use the standard global allocation and deallocation functions
(operator new and related functions). Use of these functions by HotSpot
code is disabled for some platforms.</p>
<p>Rationale: HotSpot often uses "resource" or "arena" allocation. Even
where heap allocation is used, the standard global functions are avoided
in favor of wrappers around malloc and free that support the VM's Native
Memory Tracking (NMT) feature. Typically, uses of the global operator
new are inadvertent and therefore often associated with memory
leaks.</p>
<p>Native memory allocation failures are often treated as
non-recoverable. The place where "out of memory" is (first) detected may
be an innocent bystander, unrelated to the actual culprit.</p>
<h3 id="class-inheritance">Class Inheritance</h3>
<p>Use public single inheritance.</p>
<p>Prefer composition rather than non-public inheritance.</p>
<p>Restrict inheritance to the "is-a" case; use composition rather than
non-is-a related inheritance.</p>
<p>Avoid multiple inheritance. Never use virtual inheritance.</p>
<h3 id="namespaces">Namespaces</h3>
<p>Avoid using namespaces. HotSpot code normally uses "all static"
classes rather than namespaces for grouping. An "all static" class is
not instantiable, has only static members, and is normally derived
(possibly indirectly) from the helper class <code>AllStatic</code>.</p>
<p>Benefits of using such classes include:</p>
<ul>
<li><p>Provides access control for members, which is unavailable with
namespaces.</p></li>
<li><p>Avoids <a href="https://en.cppreference.com/w/cpp/language/adl"
title="Argument Dependent Lookup">Argument Dependent Lookup</a>
(ADL).</p></li>
<li><p>Closed for additional members. Namespaces allow names to be added
in multiple contexts, making it harder to see the complete API.</p></li>
</ul>
<p>Namespaces should be used only in cases where one of those "benefits"
is actually a hindrance.</p>
<p>In particular, don't use anonymous namespaces. They seem like they
should be useful, and indeed have some real benefits for naming and
generated code size on some platforms. Unfortunately, debuggers don't
seem to like them at all.</p>
<p><a
href="https://groups.google.com/forum/#!topic/mozilla.dev.platform/KsaG3lEEaRM"
class="uri">https://groups.google.com/forum/#!topic/mozilla.dev.platform/KsaG3lEEaRM</a><br>
Suggests Visual Studio debugger might not be able to refer to anonymous
namespace symbols, so can't set breakpoints in them. Though the
discussion seems to go back and forth on that.</p>
<p><a
href="https://firefox-source-docs.mozilla.org/code-quality/coding-style/coding_style_cpp.html"
class="uri">https://firefox-source-docs.mozilla.org/code-quality/coding-style/coding_style_cpp.html</a><br>
Search for "Anonymous namespaces" Suggests preferring "static" to
anonymous namespaces where applicable, because of poor debugger support
for anonymous namespaces.</p>
<p><a href="https://sourceware.org/bugzilla/show_bug.cgi?id=16874"
class="uri">https://sourceware.org/bugzilla/show_bug.cgi?id=16874</a><br>
Bug for similar gdb problems.</p>
<h3 id="c-standard-library">C++ Standard Library</h3>
<p>Avoid using the C++ Standard Library.</p>
<p>Historically, HotSpot has mostly avoided use of the Standard
Library.</p>
<p>(It used to be impossible to use most of it in shared code, because
the build configuration for Solaris with Solaris Studio made all but a
couple of pieces inaccessible. Support for header-only parts was added
in mid-2017. Support for Solaris was removed in 2020.)</p>
<p>Some reasons for this include</p>
<ul>
<li><p>Exceptions. Perhaps the largest core issue with adopting the use
of Standard Library facilities is exceptions. HotSpot does not use
exceptions and, for platforms which allow doing so, builds with them
turned off. Many Standard Library facilities implicitly or explicitly
use exceptions.</p></li>
<li><p><code>assert</code>. An issue that is quickly encountered is the
<code>assert</code> macro name collision (<a
href="https://bugs.openjdk.org/browse/JDK-8007770">JDK-8007770</a>).
Some mechanism for addressing this would be needed before much of the
Standard Library could be used. (Not all Standard Library
implementations use assert in header files, but some do.)</p></li>
<li><p>Memory allocation. HotSpot requires explicit control over where
allocations occur. The C++98/03 <code>std::allocator</code> class is too
limited to support our usage. (Changes in more recent Standards may
remove this limitation.)</p></li>
<li><p>Implementation vagaries. Bugs, or simply different implementation
choices, can lead to different behaviors among the various Standard
Libraries we need to deal with.</p></li>
<li><p>Inconsistent naming conventions. HotSpot and the C++ Standard use
different naming conventions. The coexistence of those different
conventions might appear jarring and reduce readability.</p></li>
</ul>
<p>There are a few exceptions to this rule.</p>
<ul>
<li><code>#include &lt;new&gt;</code> to use placement <code>new</code>,
<code>std::nothrow</code>, and <code>std::nothrow_t</code>.</li>
<li><code>#include &lt;limits&gt;</code> to use
<code>std::numeric_limits</code>.</li>
<li><code>#include &lt;type_traits&gt;</code> with some restrictions,
listed below.</li>
<li><code>#include &lt;cstddef&gt;</code> to use
<code>std::nullptr_t</code> and <code>std::max_align_t</code>.</li>
</ul>
<p>Certain restrictions apply to the declarations provided by
<code>&lt;type_traits&gt;</code>.</p>
<ul>
<li>The <code>alignof</code> operator should be used rather than
<code>std::alignment_of&lt;&gt;</code>.</li>
</ul>
<p>TODO: Rather than directly #including (permitted) Standard Library
headers, use a convention of #including wrapper headers (in some
location like hotspot/shared/stdcpp). This provides a single place for
dealing with issues we might have for any given header, esp.
platform-specific issues.</p>
<h3 id="type-deduction">Type Deduction</h3>
<p>Use type deduction only if it makes the code clearer or safer. Do not
use it merely to avoid the inconvenience of writing an explicit type,
unless that type is itself difficult to write. An example of the latter
is a function template return type that depends on template parameters
in a non-trivial way.</p>
<p>There are several contexts where types are deduced.</p>
<ul>
<li><p>Function argument deduction. This is always permitted, and indeed
encouraged. It is nearly always better to allow the type of a function
template argument to be deduced rather than explicitly
specified.</p></li>
<li><p><code>auto</code> variable declarations (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf">n1984</a>)<br>
For local variables, this can be used to make the code clearer by
eliminating type information that is obvious or irrelevant. Excessive
use can make code much harder to understand.</p></li>
<li><p>Function return type deduction (<a
href="https://isocpp.org/files/papers/N3638.html">n3638</a>)<br> Only
use if the function body has a very small number of <code>return</code>
statements, and generally relatively little other code.</p></li>
<li><p>Also see <a href="#lambdaexpressions">lambda
expressions</a>.</p></li>
</ul>
<h3 id="expression-sfinae">Expression SFINAE</h3>
<p><a href="https://en.cppreference.com/w/cpp/language/sfinae"
title="Substitution Failure Is Not An Error">Substitution Failure Is Not
An Error</a> (SFINAE) is a template metaprogramming technique that makes
use of template parameter substitution failures to make compile-time
decisions.</p>
<p>C++11 relaxed the rules for what constitutes a hard-error when
attempting to substitute template parameters with template arguments,
making most deduction errors be substitution errors; see (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html">n2634</a>).
This makes <a href="https://en.cppreference.com/w/cpp/language/sfinae"
title="Substitution Failure Is Not An Error">SFINAE</a> more powerful
and easier to use. However, the implementation complexity for this
change is significant, and this seems to be a place where obscure
corner-case bugs in various compilers can be found. So while this
feature can (and indeed should) be used (and would be difficult to
avoid), caution should be used when pushing to extremes.</p>
<p>Here are a few closely related example bugs:<br> <a
href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95468"
class="uri">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95468</a><br>
<a
href="https://developercommunity.visualstudio.com/content/problem/396562/sizeof-deduced-type-is-sometimes-not-a-constant-ex.html"
class="uri">https://developercommunity.visualstudio.com/content/problem/396562/sizeof-deduced-type-is-sometimes-not-a-constant-ex.html</a></p>
<h3 id="enum">enum</h3>
<p>Where appropriate, <em>scoped-enums</em> should be used. (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf">n2347</a>)</p>
<p>Use of <em>unscoped-enums</em> is permitted, though ordinary
constants may be preferable when the automatic initializer feature isn't
used.</p>
<p>The underlying type (the <em>enum-base</em>) of an unscoped enum type
should always be specified explicitly. When unspecified, the underlying
type is dependent on the range of the enumerator values and the
platform.</p>
<p>The underlying type of a <em>scoped-enum</em> should also be
specified explicitly if conversions may be applied to values of that
type.</p>
<p>Due to bugs in certain (very old) compilers, there is widespread use
of enums and avoidance of in-class initialization of static integral
constant members. Compilers having such bugs are no longer supported.
Except where an enum is semantically appropriate, new code should use
integral constants.</p>
<h3 id="alignas">alignas</h3>
<p><em>Alignment-specifiers</em> (<code>alignas</code> <a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf">n2341</a>)
are permitted, with restrictions.</p>
<p><em>Alignment-specifiers</em> are permitted when the requested
alignment is a <em>fundamental alignment</em> (not greater than
<code>alignof(std::max_align_t)</code> <a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf">C++14
3.11/2</a>).</p>
<p><em>Alignment-specifiers</em> with an <em>extended alignment</em>
(greater than <code>alignof(std::max_align_t)</code> <a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf">C++14
3.11/3</a>) may only be used to align variables with static or automatic
storage duration (<a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf">C++14
3.7.1, 3.7.3</a>). As a consequence, <em>over-aligned types</em> are
forbidden; this may change if HotSpot updates to using C++17 or later
(<a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0035r4.html">p0035r4</a>).</p>
<p>Large <em>extended alignments</em> should be avoided, particularly
for stack allocated objects. What is a large value may depend on the
platform and configuration. There may also be hard limits for some
platforms.</p>
<p>An <em>alignment-specifier</em> must always be applied to a
definition (<a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf">C++14
10.6.2/6</a>). (C++ allows an <em>alignment-specifier</em> to optionally
also be applied to a declaration, so long as the definition has
equivalent alignment. There isn't any known benefit from duplicating the
alignment in a non-definition declaration, so such duplication should be
avoided in HotSpot code.)</p>
<p>Enumerations are forbidden from having <em>alignment-specifiers</em>.
Aligned enumerations were originally permitted but insufficiently
specified, and were later (C++20) removed (<a
href="https://cplusplus.github.io/CWG/issues/2354.html">CWG 2354</a>).
Permitting such usage in HotSpot now would just cause problems in the
future.</p>
<p><em>Alignment-specifiers</em> are forbidden in <code>typedef</code>
and <em>alias-declarations</em>. This may work or may have worked in
some versions of some compilers, but was later (C++14) explicitly
disallowed (<a
href="https://cplusplus.github.io/CWG/issues/1437.html">CWG
1437</a>).</p>
<p>The HotSpot macro <code>ATTRIBUTE_ALIGNED</code> provides similar
capabilities for platforms that define it. This macro predates the use
by HotSpot of C++ versions providing <code>alignas</code>. New code
should use <code>alignas</code>.</p>
<h3 id="thread_local">thread_local</h3>
<p>Avoid use of <code>thread_local</code> (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm">n2659</a>);
and instead, use the HotSpot macro <code>THREAD_LOCAL</code>, for which
the initializer must be a constant expression. When
<code>thread_local</code> must be used, use the Hotspot macro
<code>APPROVED_CPP_THREAD_LOCAL</code> to indicate that the use has been
given appropriate consideration.</p>
<p>As was discussed in the review for <a
href="https://mail.openjdk.org/pipermail/hotspot-dev/2019-September/039487.html">JDK-8230877</a>,
<code>thread_local</code> allows dynamic initialization and destruction
semantics. However, that support requires a run-time penalty for
references to non-function-local <code>thread_local</code> variables
defined in a different translation unit, even if they don't need dynamic
initialization. Dynamic initialization and destruction of non-local
<code>thread_local</code> variables also has the same ordering problems
as for ordinary non-local variables. So we avoid use of
<code>thread_local</code> in general, limiting its use to only those
cases where dynamic initialization or destruction are essential. See <a
href="https://bugs.openjdk.org/browse/JDK-8282469">JDK-8282469</a> for
further discussion.</p>
<h3 id="nullptr">nullptr</h3>
<p>Use <code>nullptr</code> (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf">n2431</a>)
rather than <code>NULL</code>. See the paper for reasons to avoid
<code>NULL</code>.</p>
<p>Don't use (constant expression or literal) 0 for pointers. Note that
C++14 removed non-literal 0 constants from <em>null pointer
constants</em>, though some compilers continue to treat them as such.
For historical reasons there may be lingering uses of 0 as a
pointer.</p>
<h3 id="atomic">&lt;atomic&gt;</h3>
<p>Do not use facilities provided by the <code>&lt;atomic&gt;</code>
header (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html">n2427</a>),
(<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm">n2752</a>);
instead, use the HotSpot <code>Atomic</code> class and related
facilities.</p>
<p>Atomic operations in HotSpot code must have semantics which are
consistent with those provided by the JDK's compilers for Java. There
are platform-specific implementation choices that a C++ compiler might
make or change that are outside the scope of the C++ Standard, and might
differ from what the Java compilers implement.</p>
<p>In addition, HotSpot <code>Atomic</code> has a concept of
"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.</p>
<h3 id="uniform-initialization">Uniform Initialization</h3>
<p>The use of <em>uniform initialization</em> (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm">n2672</a>),
also known as <em>brace initialization</em>, is permitted.</p>
<p>Some relevant sections from cppreference.com:</p>
<ul>
<li><a
href="https://en.cppreference.com/w/cpp/language/initialization">initialization</a></li>
<li><a
href="https://en.cppreference.com/w/cpp/language/value_initialization">value
initialization</a></li>
<li><a
href="https://en.cppreference.com/w/cpp/language/direct_initialization">direct
initialization</a></li>
<li><a
href="https://en.cppreference.com/w/cpp/language/list_initialization">list
initialization</a></li>
<li><a
href="https://en.cppreference.com/w/cpp/language/aggregate_initialization">aggregate
initialization</a></li>
</ul>
<p>Although related, the use of <code>std::initializer_list</code>
remains forbidden, as part of the avoidance of the C++ Standard Library
in HotSpot code.</p>
<h3 id="local-function-objects">Local Function Objects</h3>
<ul>
<li>Local function objects, including lambda expressions, may be
used.</li>
<li>Lambda expressions must only be used as a downward value.</li>
<li>Prefer <code>[&amp;]</code> as the capture list of a lambda
expression.</li>
<li>Return type deduction for lambda expressions is permitted, and
indeed encouraged.</li>
<li>An empty parameter list for a lambda expression may be elided.</li>
<li>A lambda expression must not be <code>mutable</code>.</li>
<li>Generic lambda expressions are permitted.</li>
<li>Lambda expressions should be relatively simple.</li>
<li>Anonymous lambda expressions should not overly clutter the enclosing
expression.</li>
<li>An anonymous lambda expression must not be directly invoked.</li>
<li>Bind expressions are forbidden.</li>
</ul>
<p>Single-use function objects can be defined locally within a function,
directly at the point of use. This is an alternative to having a
function or function object class defined at class or namespace
scope.</p>
<p>This usage was somewhat limited by C++03, which does not permit such
a class to be used as a template parameter. That restriction was removed
by C++11 (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm">n2657</a>).
Use of this feature is permitted.</p>
<p>Many HotSpot protocols involve "function-like" objects that involve
some named member function rather than a call operator. For example, a
function that performs some action on all threads might be written
as</p>
<pre><code>void do_something() {
struct DoSomething : public ThreadClosure {
virtual void do_thread(Thread* t) {
... do something with t ...
}
} closure;
Threads::threads_do(&amp;closure);
}</code></pre>
<p>HotSpot code has historically usually placed the DoSomething class at
namespace (or sometimes class) scope. This separates the function's code
from its use, often to the detriment of readability. It requires giving
the class a globally unique name (if at namespace scope). It also loses
the information that the class is intended for use in exactly one place,
and does not have any subclasses. (However, the latter can now be
indicated by declaring it <code>final</code>.) Often, for simplicity, a
local class will skip things like access control and accessor functions,
giving the enclosing function direct access to the implementation and
eliminating some boilerplate that might be provided if the class is in
some outer (more accessible) scope. On the other hand, if there is a lot
of surrounding code in the function body or the local class is of
significant size, defining it locally can increase clutter and reduce
readability.</p>
<p><a name="lambdaexpressions"></a> C++11 added <em>lambda
expressions</em> as a new way to write a function object. Simple lambda
expressions can be significantly more concise than a function object,
eliminating a lot of boiler-plate. On the other hand, a complex lambda
expression may not provide much, if any, readability benefit compared to
an ordinary function object. Also, while a lambda can encapsulate a call
to a "function-like" object, it cannot be used in place of such.</p>
<p>A common use for local functions is as one-use <a
href="https://en.cppreference.com/w/cpp/language/raii"
title="Resource Acquisition Is Initialization">RAII</a> objects. The
amount of boilerplate for a function object class (local or not) makes
such usage somewhat clumsy and verbose. But with the help of a small
amount of supporting utility code, lambdas work particularly well for
this use case.</p>
<p>Another use for local functions is <a
href="https://en.wikipedia.org/wiki/Partial_application"
title="Partial Application">partial application</a>. Again here, lambdas
are typically much simpler and less verbose than function object
classes.</p>
<p>Because of these benefits, lambda expressions are permitted in
HotSpot code, with some restrictions and usage guidance. An anonymous
lambda is one which is passed directly as an argument. A named lambda is
the value of a variable, which is its name.</p>
<p>Lambda expressions should only be passed downward. In particular, a
lambda should not be returned from a function or stored in a global
variable, whether directly or as the value of a member of some other
object. Lambda capture is syntactically subtle (by design), and
propagating a lambda in such ways can easily pass references to captured
values to places where they are no longer valid. In particular, members
of the enclosing <code>this</code> object are effectively captured by
reference, even if the default capture is by-value. For such uses-cases
a function object class should be used to make the desired value
capturing and propagation explicit.</p>
<p>Limiting the capture list to <code>[&amp;]</code> (implicitly capture
by reference) is a simplifying restriction that still provides good
support for HotSpot usage, while reducing the cases a reader must
recognize and understand.</p>
<ul>
<li><p>Many common lambda uses require reference capture. Not permitting
it would substantially reduce the utility of lambdas.</p></li>
<li><p>Referential transparency. Implicit reference capture makes
variable references in the lambda body have the same meaning they would
have in the enclosing code. There isn't a semantic barrier across which
the meaning of a variable changes.</p></li>
<li><p>Explicit reference capture introduces significant clutter,
especially when lambda expressions are relatively small and simple, as
they should be in HotSpot code.</p></li>
<li><p>There are a number of reasons why by-value capture might be used,
but for the most part they don't apply to HotSpot code, given other
usage restrictions.</p>
<ul>
<li><p>A primary use-case for by-value capture is to support escaping
uses, where values captured by-reference might become invalid. That
use-case doesn't apply if only downward lambdas are used.</p></li>
<li><p>By-value capture can also make a lambda-local copy for mutation,
which requires making the lambda <code>mutable</code>; see
below.</p></li>
<li><p>By-value capture might be viewed as an optimization, avoiding any
overhead for reference capture of cheap to copy values. But the compiler
can often eliminate any such overhead.</p></li>
<li><p>By-value capture by a non-<code>mutable</code> lambda makes the
captured values const, preventing any modification by the lambda and
making the captured value unaffected by modifications to the outer
variable. But this only applies to captured auto variables, not member
variables, and is inconsistent with referential transparency.</p></li>
</ul></li>
<li><p>Non-capturing lambdas (with an empty capture list -
<code>[]</code>) have limited utility. There are cases where no captures
are required (pure functions, for example), but if the function is small
and simple then that's obvious anyway.</p></li>
<li><p>Capture initializers (a C++14 feature - <a
href="https://isocpp.org/files/papers/N3649.html">N3649</a>) are not
permitted. Capture initializers inherently increase the complexity of
the capture list, and provide little benefit over an additional in-scope
local variable.</p></li>
</ul>
<p>The use of <code>mutable</code> 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.</p>
<p>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.</p>
<p>Some reasons to prefer a named lambda instead of an anonymous lambda
are</p>
<ul>
<li><p>The body contains non-trivial control flow or declarations or
other nested constructs.</p></li>
<li><p>Its role in an argument list is hard to guess without examining
the function declaration. Give it a name that indicates its
purpose.</p></li>
<li><p>It has an unusual capture list.</p></li>
<li><p>It has a complex explicit return type or parameter
types.</p></li>
</ul>
<p>Lambda expressions, and particularly anonymous lambda expressions,
should be simple and compact. One-liners are good. Anonymous lambdas
should usually be limited to a couple lines of body code. More complex
lambdas should be named. A named lambda should not clutter the enclosing
function and make it long and complex; do continue to break up large
functions via the use of separate helper functions.</p>
<p>An anonymous lambda expression should either be a one-liner in a
one-line expression, or isolated in its own set of lines. Don't place
part of a lambda expression on the same line as other arguments to a
function. The body of a multi-line lambda argument should be indented
from the start of the capture list, as if that were the start of an
ordinary function definition. The body of a multi-line named lambda
should be indented one step from the variable's indentation.</p>
<p>Some examples:</p>
<ol type="1">
<li><p><code>foo([&amp;] { ++counter; });</code></p></li>
<li><p><code>foo(x, [&amp;] { ++counter; });</code></p></li>
<li><p><code>foo([&amp;] { if (predicate) ++counter; });</code></p></li>
<li><p><code>foo([&amp;] { auto tmp = process(x); tmp.f(); return tmp.g(); })</code></p></li>
<li><p>Separate one-line lambda from other arguments:</p>
<pre><code>foo(c.begin(), c.end(),
[&amp;] (const X&amp; x) { do_something(x); return x.value(); });</code></pre></li>
<li><p>Indentation for multi-line lambda:</p>
<pre><code>c.do_entries([&amp;] (const X&amp; x) {
do_something(x, a);
do_something1(x, b);
do_something2(x, c);
});</code></pre></li>
<li><p>Separate multi-line lambda from other arguments:</p>
<pre><code>foo(c.begin(), c.end(),
[&amp;] (const X&amp; x) {
do_something(x, a);
do_something1(x, b);
do_something2(x, c);
});</code></pre></li>
<li><p>Multi-line named lambda:</p>
<pre><code>auto do_entry = [&amp;] (const X&amp; x) {
do_something(x, a);
do_something1(x, b);
do_something2(x, c);
};</code></pre></li>
</ol>
<p>Item 4, and especially items 6 and 7, are pushing the simplicity
limits for anonymous lambdas. Item 6 might be better written using a
named lambda:</p>
<pre><code>c.do_entries(do_entry);</code></pre>
<p>Note that C++11 also added <em>bind expressions</em> as a way to
write a function object for partial application, using
<code>std::bind</code> and related facilities from the Standard Library.
<code>std::bind</code> generalizes and replaces some of the binders from
C++03. Bind expressions are not permitted in HotSpot code. They don't
provide enough benefit over lambdas or local function classes in the
cases where bind expressions are applicable to warrant the introduction
of yet another mechanism in this space into HotSpot code.</p>
<p>References:</p>
<ul>
<li>Local and unnamed types as template parameters (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm">n2657</a>)</li>
<li>New wording for C++0x lambdas (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2927.pdf">n2927</a>)</li>
<li>Generalized lambda capture (init-capture) (<a
href="https://isocpp.org/files/papers/N3648.html">N3648</a>)</li>
<li>Generic (polymorphic) lambda expressions (<a
href="https://isocpp.org/files/papers/N3649.html">N3649</a>)</li>
</ul>
<p>References from C++17</p>
<ul>
<li>Wording for constexpr lambda (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0170r1.pdf">p0170r1</a>)</li>
<li>Lambda capture of *this by Value (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0018r3.html">p0018r3</a>)</li>
</ul>
<p>References from C++20</p>
<ul>
<li>Allow lambda capture [=, this] (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0409r2.html">p0409r2</a>)</li>
<li>Familiar template syntax for generic lambdas (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0428r2.pdf">p0428r2</a>)</li>
<li>Simplifying implicit lambda capture (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0588r1.html">p0588r1</a>)</li>
<li>Default constructible and assignable stateless lambdas (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0624r2.pdf">p0624r2</a>)</li>
<li>Lambdas in unevaluated contexts (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0315r4.pdf">p0315r4</a>)</li>
<li>Allow pack expansion in lambda init-capture (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0780r2.html">p0780r2</a>)
(<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2095r0.html">p2095r0</a>)</li>
<li>Deprecate implicit capture of this via [=] (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0806r2.html">p0806r2</a>)</li>
</ul>
<p>References from C++23</p>
<ul>
<li>Make () more optional for lambdas (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1102r2.html">p1102r2</a>)</li>
</ul>
<h3 id="inheriting-constructors">Inheriting constructors</h3>
<p>Do not use <em>inheriting constructors</em> (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm">n2540</a>).</p>
<p>C++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 (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html"
title="p0136r1">p0136r1</a> 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.</p>
<p>Note that gcc7 provides the <code>-fnew-inheriting-ctors</code>
option to use the <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html"
title="p0136r1">p0136r1</a> semantics. This is enabled by default when
using C++17 or later. It is also enabled by default for
<code>fabi-version=11</code> (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.</p>
<h3 id="attributes">Attributes</h3>
<p>The use of some attributes (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf">n2761</a>)
(listed below) is permitted. (Note that some of the attributes defined
in that paper didn't make it into the final specification.)</p>
<p>Attributes are syntactically permitted in a broad set of locations,
but specific attributes are only permitted in a subset of those
locations. In some cases an attribute that appertains to a given element
may be placed in any of several locations with the same meaning. In
those cases HotSpot has a preferred location.</p>
<ul>
<li>An attribute that appertains to a function is placed at the
beginning of the function's declaration, rather than between the
function name and the parameter list.</li>
</ul>
<p>Only the following attributes are permitted:</p>
<ul>
<li><code>[[noreturn]]</code></li>
</ul>
<p>The following attributes are expressly forbidden:</p>
<ul>
<li><code>[[carries_dependency]]</code> - Related to
<code>memory_order_consume</code>.</li>
<li><code>[[deprecated]]</code> - Not relevant in HotSpot code.</li>
</ul>
<h3 id="additional-permitted-features">Additional Permitted
Features</h3>
<ul>
<li><p><code>alignof</code> (<a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf">n2341</a>)</p></li>
<li><p><code>constexpr</code> (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf">n2235</a>)
(<a
href="https://isocpp.org/files/papers/N3652.html">n3652</a>)</p></li>
<li><p>Sized deallocation (<a
href="https://isocpp.org/files/papers/n3778.html">n3778</a>)</p></li>
<li><p>Variadic templates (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf">n2242</a>)
(<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf">n2555</a>)</p></li>
<li><p>Static assertions (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html">n1720</a>)</p></li>
<li><p><code>decltype</code> (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf">n2343</a>)
(<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf">n3276</a>)</p></li>
<li><p>Right angle brackets (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html">n1757</a>)</p></li>
<li><p>Default template arguments for function templates (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226">CWG
D226</a>)</p></li>
<li><p>Template aliases (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf">n2258</a>)</p></li>
<li><p>Delegating constructors (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf">n1986</a>)</p></li>
<li><p>Explicit conversion operators (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf">n2437</a>)</p></li>
<li><p>Standard Layout Types (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm">n2342</a>)</p></li>
<li><p>Defaulted and deleted functions (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">n2346</a>)</p></li>
<li><p>Dynamic initialization and destruction with concurrency (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm">n2660</a>)</p></li>
<li><p><code>final</code> virtual specifiers for classes and virtual
functions (<a
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm">n2928</a>),
(<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm">n3206</a>),
(<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm">n3272</a>)</p></li>
<li><p><code>override</code> virtual specifiers for virtual functions
(<a
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm">n2928</a>),
(<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm">n3206</a>),
(<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm">n3272</a>)</p></li>
<li><p>Range-based <code>for</code> loops (<a
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html">n2930</a>)
(<a
href="https://en.cppreference.com/w/cpp/language/range-for">range-for</a>)</p></li>
<li><p>Unrestricted Unions (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf">n2544</a>)</p></li>
</ul>
<h3 id="excluded-features">Excluded Features</h3>
<ul>
<li><p>New string and character literals</p>
<ul>
<li>New character types (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html">n2249</a>)</li>
<li>Unicode string literals (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm">n2442</a>)</li>
<li>Raw string literals (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm">n2442</a>)</li>
<li>Universal character name literals (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html">n2170</a>)</li>
</ul>
<p>HotSpot doesn't need any of the new character and string literal
types.</p></li>
<li><p>User-defined literals (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf">n2765</a>)
— User-defined literals should not be added casually, but only through a
proposal to add a specific UDL.</p></li>
<li><p>Inline namespaces (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm">n2535</a>)
— HotSpot makes very limited use of namespaces.</p></li>
<li><p><code>using namespace</code> directives. In particular, don't use
<code>using namespace std;</code> to avoid needing to qualify Standard
Library names.</p></li>
<li><p>Propagating exceptions (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html">n2179</a>)
— HotSpot does not permit the use of exceptions, so this feature isn't
useful.</p></li>
<li><p>Avoid non-local variables with non-constexpr initialization. In
particular, avoid variables with types requiring non-trivial
initialization or destruction. Initialization order problems can be
difficult to deal with and lead to surprises, as can destruction
ordering. HotSpot doesn't generally try to cleanup on exit, and running
destructors at exit can also lead to problems.</p></li>
<li><p>Avoid most operator overloading, preferring named functions. When
operator overloading is used, ensure the semantics conform to the normal
expected behavior of the operation.</p></li>
<li><p>Avoid most implicit conversion constructors and (implicit or
explicit) conversion operators. (Note that conversion to
<code>bool</code> isn't needed in HotSpot code because of the "no
implicit boolean" guideline.)</p></li>
<li><p>Avoid <code>goto</code> statements.</p></li>
</ul>
<h3 id="undecided-features">Undecided Features</h3>
<p>This list is incomplete; it serves to explicitly call out some
features that have not yet been discussed.</p>
<ul>
<li><p>Trailing return type syntax for functions (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm">n2541</a>)</p></li>
<li><p>Variable templates (<a
href="https://isocpp.org/files/papers/N3651.pdf">n3651</a>)</p></li>
<li><p>Member initializers and aggregates (<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html">n3653</a>)</p></li>
<li><p>Rvalue references and move semantics</p></li>
</ul>
</body>
</html>