mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 01:19:28 +01:00
1996 lines
106 KiB
HTML
1996 lines
106 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="#changing-this-document"
|
|
id="toc-changing-this-document">Changing this Document</a></li>
|
|
<li><a href="#why-care-about-style" id="toc-why-care-about-style">Why
|
|
Care About Style?</a></li>
|
|
<li><a href="#counterexamples"
|
|
id="toc-counterexamples">Counterexamples</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="#avoid-implicit-conversions-to-bool"
|
|
id="toc-avoid-implicit-conversions-to-bool">Avoid implicit conversions
|
|
to bool</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="#trailing-return-type-syntax-for-functions"
|
|
id="toc-trailing-return-type-syntax-for-functions">Trailing return type
|
|
syntax for functions</a></li>
|
|
<li><a href="#non-type-template-parameter-values"
|
|
id="toc-non-type-template-parameter-values">Non-type template parameter
|
|
values</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"><atomic></a></li>
|
|
<li><a href="#variable-templates-and-inline-variables"
|
|
id="toc-variable-templates-and-inline-variables">Variable Templates and
|
|
Inline Variables</a></li>
|
|
<li><a href="#initializing-variables-with-static-storage-duration"
|
|
id="toc-initializing-variables-with-static-storage-duration">Initializing
|
|
variables with static storage duration</a></li>
|
|
<li><a href="#uniform-initialization"
|
|
id="toc-uniform-initialization">Uniform Initialization</a></li>
|
|
<li><a href="#mandatory-copy-elision"
|
|
id="toc-mandatory-copy-elision">Mandatory Copy Elision</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="#noexcept" id="toc-noexcept">noexcept</a></li>
|
|
<li><a href="#enhanced-selection-statements"
|
|
id="toc-enhanced-selection-statements">Enhanced selection
|
|
statements</a></li>
|
|
<li><a href="#expression-evaluation-order"
|
|
id="toc-expression-evaluation-order">Expression Evaluation
|
|
Order</a></li>
|
|
<li><a href="#compatibility-with-c11"
|
|
id="toc-compatibility-with-c11">Compatibility with C11</a></li>
|
|
<li><a href="#additional-permitted-features"
|
|
id="toc-additional-permitted-features">Additional Permitted
|
|
Features</a></li>
|
|
</ul></li>
|
|
<li><a href="#forbidden-features" id="toc-forbidden-features">Forbidden
|
|
Features</a>
|
|
<ul>
|
|
<li><a href="#structured-bindings"
|
|
id="toc-structured-bindings">Structured Bindings</a></li>
|
|
<li><a href="#file-system-library" id="toc-file-system-library">File
|
|
System Library</a></li>
|
|
<li><a href="#aggregate-extensions"
|
|
id="toc-aggregate-extensions">Aggregate Extensions</a></li>
|
|
<li><a href="#additional-forbidden-features"
|
|
id="toc-additional-forbidden-features">Additional Forbidden
|
|
Features</a></li>
|
|
</ul></li>
|
|
<li><a href="#undecided-features" id="toc-undecided-features">Undecided
|
|
Features</a>
|
|
<ul>
|
|
<li><a href="#stdoptional"
|
|
id="toc-stdoptional">std::optional<></a></li>
|
|
<li><a href="#stdbyte" id="toc-stdbyte">std::byte</a></li>
|
|
<li><a href="#string-views" id="toc-string-views">String Views</a></li>
|
|
<li><a href="#substring-and-subsequence-searching"
|
|
id="toc-substring-and-subsequence-searching">Substring and Subsequence
|
|
Searching</a></li>
|
|
<li><a href="#new-and-delete-with-over-aligned-data"
|
|
id="toc-new-and-delete-with-over-aligned-data"><code>new</code> and
|
|
<code>delete</code> with Over-Aligned Data</a></li>
|
|
<li><a href="#stdto_chars-and-stdfrom_chars"
|
|
id="toc-stdto_chars-and-stdfrom_chars"><code>std::to_chars()</code> and
|
|
<code>std::from_chars</code></a></li>
|
|
<li><a href="#stdlaunder"
|
|
id="toc-stdlaunder"><code>std::launder()</code></a></li>
|
|
<li><a href="#additional-undecided-features"
|
|
id="toc-additional-undecided-features">Additional 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="changing-this-document">Changing this Document</h3>
|
|
<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>
|
|
<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">Counterexamples</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>
|
|
<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>
|
|
<h4 id="conventions-for-lock-free-code">Conventions for Lock-free
|
|
Code</h4>
|
|
<p>Sometimes variables are accessed concurrently without appropriate
|
|
synchronization context, such as a held mutex or at a safepoint. In such
|
|
cases the variable should be declared <code>volatile</code> and it
|
|
should NOT be accessed as a normal C++ lvalue. Rather, access should be
|
|
performed via functions from <code>Atomic</code>, such as
|
|
<code>Atomic::load</code>, <code>Atomic::store</code>, etc.</p>
|
|
<p>This special formulation makes it more clear to maintainers that the
|
|
variable is accessed concurrently in a lock-free manner.</p>
|
|
<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>Keep the include lines within a section alphabetically sorted by
|
|
their lowercase value. If an include must be out of order for
|
|
correctness, suffix with it a comment such as
|
|
<code>// do not reorder</code>. Source code processing tools can also
|
|
use this hint.</p></li>
|
|
<li><p>Put conditional inclusions (<code>#if ...</code>) at the end of
|
|
the section of HotSpot include lines. This also applies to
|
|
macro-expanded includes of platform dependent files.</p></li>
|
|
<li><p>Put system includes in a section after the HotSpot include lines
|
|
with a blank line separating the two sections.</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 with a blank line separating it from the
|
|
rest of the include lines. 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>Do not include a .hpp file if the corresponding .inline.hpp file
|
|
is included.</p></li>
|
|
<li><p>Use include guards for .hpp and .inline.hpp files. The name of
|
|
the defined guard should be derived from the full search path of the
|
|
file relative to the hotspot source directory. The guard should be all
|
|
upper case with all paths separators and periods replaced by
|
|
underscores.</p></li>
|
|
<li><p>Some build configurations use precompiled headers to speed up the
|
|
build times. The precompiled headers are included in the precompiled.hpp
|
|
file. Note that precompiled.hpp is just a build time optimization, so
|
|
don't rely on it to resolve include problems.</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><<</code>, <code>&</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="avoid-implicit-conversions-to-bool">Avoid implicit conversions
|
|
to bool</h3>
|
|
<ul>
|
|
<li>Use <code>bool</code> for boolean values.</li>
|
|
<li>Do not use ints or pointers as (implicit) booleans with
|
|
<code>&&</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 non-boolean declarations in <em>condition</em> forms,
|
|
i.e. don't use <code>if (T v = value) { ... }</code>. But see <a
|
|
href="#enhanced-selection-statements">Enhanced selection
|
|
statements</a>.</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>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++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.)</p>
|
|
<p>This section describes that subset. Features from the C++98/03
|
|
language may be used unless explicitly forbidden here. Features from
|
|
C++11, C++14, and C++17 may be explicitly permitted or explicitly
|
|
forbidden, 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 forbidden.</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, forbidden, and undecided features.</p>
|
|
<p>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.</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
|
|
(global <code>operator new</code> and related functions), other than the
|
|
non-allocating forms of those 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 <code>malloc</code> and <code>free</code>
|
|
that support the JVM's Native Memory Tracking (NMT) feature. Typically,
|
|
uses of the global <code>operator new</code> 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>Only curated parts of the C++ Standard Library may be used by HotSpot
|
|
code.</p>
|
|
<p>Functions that may throw exceptions must not be used. This is in
|
|
accordance with the HotSpot policy of <a href="#error-handling">not
|
|
using exceptions</a>.</p>
|
|
<p>Also in accordance with HotSpot policy, the <a
|
|
href="#memory-allocation">standard global allocator must not be
|
|
used</a>. This means that uses of standard container classes cannot
|
|
presently be used, as doing so requires specialization on some allocator
|
|
type that is integrated with the existing HotSpot allocation mechanisms.
|
|
(Such allocators may be provided in the future.)</p>
|
|
<p>Standard Library identifiers should usually be fully qualified;
|
|
<code>using</code> directives must not be used to bring Standard Library
|
|
identifiers into scope just to remove the need for namespace
|
|
qualification. Requiring qualification makes it easy to distinguish
|
|
between references to external libraries and code that is part of
|
|
HotSpot.</p>
|
|
<p>As with language features, Standard Library facilities are either
|
|
permitted, explicitly forbidden, or undecided (and so implicitly
|
|
forbidden).</p>
|
|
<p>Most HotSpot code should not directly <code>#include</code> C++
|
|
Standard Library headers. HotSpot provides a set of wrapper headers for
|
|
the Standard Library headers containing permitted definitions. These
|
|
wrappers are in the <code>cppstdlib</code> directory, with the same name
|
|
as the corresponding Standard Library header and a <code>.hpp</code>
|
|
extension. These wrappers provide a place for any additional code (some
|
|
of which may be platform-specific) needed to support HotSpot usage.</p>
|
|
<p>These wrappers also provide a place to document HotSpot usage,
|
|
including any restrictions. The set of wrappers and the usage
|
|
documentation should be considered part of HotSpot style. Any changes
|
|
are subject to the same process as applies to this document. (For
|
|
historical reasons, there may be many direct inclusions of some C++
|
|
Standard Library headers.)</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. On the other hand, many don't, and can be used without
|
|
concern for this issue. Others may have a useful subset that doesn't 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>).
|
|
(Not all Standard Library implementations use <code>assert</code> in
|
|
header files, but some do.) HotSpot provides a mechanism for addressing
|
|
this, by establishing a scope around the include of a library header
|
|
where the HotSpot <code>assert</code> macro is suppressed. One of the
|
|
reasons for using wrapper headers rather than directly including
|
|
standard headers is to provide a central place to deal with this issue
|
|
for each header.</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. But changes to the allocator concept in
|
|
more recent Standards removed some of the limitations, supporting
|
|
stateful allocators. HotSpot may, in the future, provide
|
|
standard-conforming allocators that are integrated with HotSpot's
|
|
existing allocation mechanisms.</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. But only selected parts of the Standard
|
|
Library are being permitted, and one of the selection criteria is
|
|
maturity. Some of these facilities are among the most heavily tested and
|
|
used C++ codes that exist.</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. However,
|
|
experience in some other code bases suggests this isn't a significant
|
|
problem, so long as Standard Library names are namespace-qualified. It
|
|
is tempting to bring the Standard Library names into scope via a
|
|
<code>using std;</code> directive. Doing so makes writing code using
|
|
those names easier, since the qualifiers don't need to be included. But
|
|
there are several reasons not to do that.</p>
|
|
<ul>
|
|
<li><p>There is a risk of future name collisions. Additional Standard
|
|
Library headers may be included, adding to the list of names being used.
|
|
Also, future versions of the Standard Library may add currently unknown
|
|
names to the headers already being included.</p></li>
|
|
<li><p>It may harm readability. Code where this is relevant is a mixture
|
|
of the local HotSpot naming conventions and the Standard Library's (or
|
|
other 3rd-party library's) naming conventions. With only unqualified
|
|
names, any distinctions from the naming conventions for the different
|
|
code sources are lost. Instead one may end up with an undifferentiated
|
|
mess, where it's not obvious whether an identifier is from local code
|
|
that is inconsistent with HotSpot style (and there's a regretable amount
|
|
of that for historical reasons), or is following some other convention.
|
|
Having the qualifiers disambiguates that.</p></li>
|
|
<li><p>It can be helpful to know, at a glance, whether the definition is
|
|
in HotSpot or elsewhere, for purposes of looking up the definition or
|
|
documentation.</p></li>
|
|
</ul></li>
|
|
</ul>
|
|
<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><code>auto</code> for non-type template parameters (<a
|
|
href="http://wg21.link/p0127r2">p0127r2</a>)<br> <code>auto</code> may
|
|
be used as a placeholder for the type of a non-type template parameter.
|
|
The type is deduced from the value provided in a template
|
|
instantiation.</p></li>
|
|
</ul>
|
|
<p><a name="function-return-type-deduction"></a> * 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>
|
|
<ul>
|
|
<li>Class template argument deduction (<a
|
|
href="http://wg21.link/n3602">n3602</a>, <a
|
|
href="http://wg21.link/p0091r3">p0091r3</a>)<br> The template arguments
|
|
of a class template may be deduced from the arguments to a constructor.
|
|
This is similar to ordinary function argument deduction, though partial
|
|
deduction with only <em>some</em> template arguments explicitly provided
|
|
is not permitted for class template argument deduction. Deduction guides
|
|
may be used to provide additional control over the deduction. As with
|
|
<code>auto</code> variable declarations, excessive use can make code
|
|
harder to understand, because explicit type information is lacking. But
|
|
it can also remove the need to be explicit about types that are either
|
|
obvious, or that are very hard to write. For example, these allow the
|
|
addition of a scope-guard mechanism with nice syntax; something like
|
|
this</li>
|
|
</ul>
|
|
<pre><code> ScopeGuard guard{[&]{ ... cleanup code ... }};</code></pre>
|
|
<ul>
|
|
<li><p>Also see <a href="#lambdaexpressions">lambda
|
|
expressions</a>.</p></li>
|
|
<li><p><code>decltype(auto)</code> should be avoided, whether for
|
|
variables, for non-type template parameters, or for function return
|
|
types. There are subtle and complex differences between this placeholder
|
|
type and <code>auto</code>. Any use would need very careful
|
|
explanation.</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="trailing-return-type-syntax-for-functions">Trailing return type
|
|
syntax for functions</h3>
|
|
<p>A function's return type may be specified after the parameters and
|
|
qualifiers (<a
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm">n2541</a>).
|
|
In such a declaration the normal return type is <code>auto</code> and
|
|
the return type is indicated by <code>-></code> followed by the type.
|
|
Although both use <code>auto</code> in the "normal" leading return type
|
|
position, this differs from <a
|
|
href="#function-return-type-deduction">function return type
|
|
deduction</a>, in that the return type is explicit rather than deduced,
|
|
but specified in a trailing position.</p>
|
|
<p>Use of trailing return types is permitted. However, the normal,
|
|
leading position for the return type is preferred. A trailing return
|
|
type should only be used where it provides some benefit. Such benefits
|
|
usually arise because a trailing return type is in a different scope
|
|
than a leading return type.</p>
|
|
<ul>
|
|
<li><p>If the function identifier is a nested name specifier, then the
|
|
trailing return type occurs in the nested scope. This may permit simpler
|
|
naming in the return type because of the different name lookup
|
|
context.</p></li>
|
|
<li><p>The trailing return type is in the scope of the parameters,
|
|
making their types accessible via <code>decltype</code>. For
|
|
example</p></li>
|
|
</ul>
|
|
<pre><code>template<typename T, typename U> auto add(T t, U u) -> decltype(t + u);</code></pre>
|
|
<p>rather than</p>
|
|
<pre><code>template<typename T, typename U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);</code></pre>
|
|
<ul>
|
|
<li>Complex calculated leading return types may obscure the normal
|
|
syntactic boundaries, making it more difficult for a reader to find the
|
|
function name and parameters. This is particularly common in cases where
|
|
the return type is being used for <a
|
|
href="https://en.cppreference.com/w/cpp/language/sfinae"
|
|
title="Substitution Failure Is Not An Error">SFINAE</a>. A trailing
|
|
return type may be preferable in such situations.</li>
|
|
</ul>
|
|
<h3 id="non-type-template-parameter-values">Non-type template parameter
|
|
values</h3>
|
|
<p>C++17 extended the arguments permitted for non-type template
|
|
parameters (<a href="http://wg21.link/n4268">n4268</a>). 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.</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"><atomic></h3>
|
|
<p>Do not use facilities provided by the <code><atomic></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="variable-templates-and-inline-variables">Variable Templates and
|
|
Inline Variables</h3>
|
|
<p>The use of variable templates (including static data member
|
|
templates) (<a href="https://wg21.link/N3651">N3651</a>) is permitted.
|
|
They provide parameterized variables and constants in a simple and
|
|
direct form, instead of requiring the use of various workarounds.</p>
|
|
<p>Variables with static storage duration and variable templates may be
|
|
declared <code>inline</code> (<a
|
|
href="https://wg21.link/p0386r2">p0386r2</a>), and this usage is
|
|
permitted. 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 <a
|
|
href="https://en.cppreference.com/w/cpp/language/definition"
|
|
title="One Definition Rule">ODR used</a>, and the behavior of the
|
|
program is as if there is exactly one variable.</p>
|
|
<p>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 <a
|
|
href="#initializing-variables-with-static-storage-duration">initialization</a>
|
|
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.</p>
|
|
<p>A <code>constexpr</code> static data member or static data member
|
|
template is implicitly <code>inline</code>. As a consequence, an <a
|
|
href="https://en.cppreference.com/w/cpp/language/definition"
|
|
title="One Definition Rule">ODR use</a> of such a member 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.)</p>
|
|
<p>Declaring a <code>thread_local</code> variable template or
|
|
<code>inline</code> variable is forbidden in HotSpot code. <a
|
|
href="#thread_local">The use of <code>thread_local</code></a> is already
|
|
heavily restricted.</p>
|
|
<h3
|
|
id="initializing-variables-with-static-storage-duration">Initializing
|
|
variables with static storage duration</h3>
|
|
<p>Variables with static storage duration and <em>dynamic
|
|
initialization</em> <a
|
|
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf">C++14
|
|
3.6.2</a>). should be avoided, unless an implementation is permitted to
|
|
perform the initialization as a static initialization. The order in
|
|
which dynamic initializations occur is incompletely specified.
|
|
Initialization order problems can be difficult to deal with and lead to
|
|
surprises.</p>
|
|
<p>Variables with static storage duration and non-trivial destructors
|
|
should be avoided. HotSpot doesn't generally try to cleanup on exit, and
|
|
running destructors at exit can lead to problems.</p>
|
|
<p>Some of the approaches used in HotSpot to avoid dynamic
|
|
initialization include:</p>
|
|
<ul>
|
|
<li><p>Use the <code>DeferredStatic<T></code> class template. Add
|
|
a call to its initialization function at an appropriate place during VM
|
|
initialization. The underlying object is never destroyed.</p></li>
|
|
<li><p>For objects of class type, use a variable whose value is a
|
|
pointer to the class, initialized to <code>nullptr</code>. Provide an
|
|
initialization function that sets the variable to a dynamically
|
|
allocated object. Add a call to that function at an appropriate place
|
|
during VM initialization. Such objects are usually never
|
|
destroyed.</p></li>
|
|
</ul>
|
|
<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="mandatory-copy-elision">Mandatory Copy Elision</h3>
|
|
<p><a href="https://en.wikipedia.org/wiki/Copy_elision">Copy elision</a>
|
|
(or <a
|
|
href="https://cn.cppreference.com/w/cpp/language/copy_elision.html">here</a>)
|
|
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.</p>
|
|
<p>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.</p>
|
|
<p>C++17 changed some cases of copy elision so that there is never a
|
|
copy/move in these cases (<a
|
|
href="http://wg21.link/p0135r1">p0135r1</a>). 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 <a href="https://en.wikipedia.org/wiki/Copy_elision#RVO"
|
|
title="Return Value Optimization">RVO</a> and more specifically <a
|
|
href="https://cn.cppreference.com/w/cpp/language/copy_elision.html"
|
|
title="Unnamed Return Value Optimization">URVO</a>.</p>
|
|
<p>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.</p>
|
|
<p>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 <a href="https://en.wikipedia.org/wiki/Copy_elision#NRVO"
|
|
title="Named Return Value Optimization">NRVO</a> may apply in that
|
|
case.)</p>
|
|
<p>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.</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>[&]</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(&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>A lambda is a constexpr function if either the parameter declaration
|
|
clause is followed by <code>constexpr</code>, or it satisfies the
|
|
requirements for a constexpr function (<a
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0170r1.pdf">p0170r1</a>).
|
|
Thus, using a lambda to package up some computation doesn't incur
|
|
unnecessary overhead or prevent use in a context required to be
|
|
compile-time evaluated (such as an array size).</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>[&]</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>By-value capture of <code>this</code> (using a capture list like
|
|
<code>[*this]</code> (<a
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0018r3.html">p0018r3</a>))
|
|
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 <code>this</code> 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
|
|
<code>this</code> 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.</p></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>
|
|
<li><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></li>
|
|
</ul>
|
|
<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([&] { ++counter; });</code></p></li>
|
|
<li><p><code>foo(x, [&] { ++counter; });</code></p></li>
|
|
<li><p><code>foo([&] { if (predicate) ++counter; });</code></p></li>
|
|
<li><p><code>foo([&] { 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(),
|
|
[&] (const X& x) { do_something(x); return x.value(); });</code></pre></li>
|
|
<li><p>Indentation for multi-line lambda:</p>
|
|
<pre><code>c.do_entries([&] (const X& 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(),
|
|
[&] (const X& 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 = [&] (const X& 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:/wg21.link/p0136r1" title="p0136r1">p0136r1</a>
|
|
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.</p>
|
|
<p><a href="http://wg21.link/p0195r0">p0195r0</a></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><a href="http://wg21.link/p0068r0">p0068r0</a> is the initial
|
|
proposal for the attributes added by C++17.)</p>
|
|
<p>Only the following attributes are permitted:</p>
|
|
<ul>
|
|
<li><code>[[noreturn]]</code></li>
|
|
<li><code>[[nodiscard]]</code> (<a
|
|
href="http://wg21.link/p0189r1">p0189r1</a>)</li>
|
|
<li><code>[[maybe_unused]]</code> (<a
|
|
href="http://wg21.link/p0212r1">p0212r1</a>)</li>
|
|
<li><code>[[fallthrough]]</code> (<a
|
|
href="http://wg21.link/p0188">p0188r1</a>)</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>
|
|
<p>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 (<a href="http://wg21.link/p0283r2">p0283r2</a>). If such an
|
|
attribute is needed in shared code, the well-established technique of
|
|
providing an <code>ATTRIBUTE_XXX</code> 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.</p>
|
|
<p>The use of <code>using</code> directives in attribute lists is also
|
|
forbidden. (<a href="http://wg21.link/p0028r0">p0028r0</a>) (<a
|
|
href="http://wg21.link/p0028r4">p0028r4</a>) 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.</p>
|
|
<h3 id="noexcept">noexcept</h3>
|
|
<p>Use of <code>noexcept</code> exception specifications (<a
|
|
href="http://wg21.link/n3050">n3050</a>) are permitted with restrictions
|
|
described below.</p>
|
|
<ul>
|
|
<li>Only the argument-less form of <code>noexcept</code> exception
|
|
specifications are permitted.</li>
|
|
<li>Allocation functions that may return <code>nullptr</code> to
|
|
indicate allocation failure must be declared <code>noexcept</code>.</li>
|
|
<li>All other uses of <code>noexcept</code> exception specifications are
|
|
forbidden.</li>
|
|
<li><code>noexcept</code> expressions are forbidden.</li>
|
|
<li>Dynamic exception specifications are forbidden.</li>
|
|
</ul>
|
|
<p>HotSpot is built with exceptions disabled, e.g. compile with
|
|
<code>-fno-exceptions</code> (gcc, clang) or no <code>/EH</code> option
|
|
(MSVC++). So why do we need to consider <code>noexcept</code> at all?
|
|
It's because <code>noexcept</code> exception specifications serve two
|
|
distinct purposes.</p>
|
|
<p>The first is to allow the compiler to avoid generating code or data
|
|
in support of exceptions being thrown by a function. But this is
|
|
unnecessary, because exceptions are disabled.</p>
|
|
<p>The second is to allow the compiler and library code to choose
|
|
different algorithms, depending on whether some function may throw
|
|
exceptions. This is only relevant to a certain set of functions.</p>
|
|
<ul>
|
|
<li><p>Some allocation functions (<code>operator new</code> and
|
|
<code>operator new[]</code>) return <code>nullptr</code> to indicate
|
|
allocation failure. If a <code>new</code> expression calls such an
|
|
allocation function, it must check for and handle that possibility.
|
|
Declaring such a function <code>noexcept</code> informs the compiler
|
|
that <code>nullptr</code> is a possible result. If an allocation
|
|
function is not declared <code>noexcept</code> then the compiler may
|
|
elide that checking and handling for a <code>new</code> expression
|
|
calling that function.</p></li>
|
|
<li><p>Certain Standard Library facilities (notably containers) provide
|
|
different guarantees for some operations (and may choose different
|
|
algorithms to implement those operations), depending on whether certain
|
|
functions (constructors, copy/move operations, swap) are nothrow or not.
|
|
They detect this using type traits that test whether a function is
|
|
declared <code>noexcept</code>. This can have a significant performance
|
|
impact if, for example, copying is chosen over a potentially throwing
|
|
move. But this isn't relevant, since HotSpot forbids the use of most
|
|
Standard Library facilities.</p></li>
|
|
</ul>
|
|
<p>HotSpot code can assume no exceptions will ever be thrown, even from
|
|
functions not declared <code>noexcept</code>. So HotSpot code doesn't
|
|
ever need to check, either with conditional exception specifications or
|
|
with <code>noexcept</code> expressions.</p>
|
|
<p>The exception specification is part of the type of a function (<a
|
|
href="http://wg21.link/p0012r1">p0012r1</a>. This likely has little
|
|
impact on HotSpot code, since the use of <code>noexcept</code> is
|
|
expected to be rare.</p>
|
|
<p>Dynamic exception specifications were deprecated in C++11. C++17
|
|
removed all but <code>throw()</code>, with that remaining a deprecated
|
|
equivalent to <code>noexcept</code>.</p>
|
|
<h3 id="enhanced-selection-statements">Enhanced selection
|
|
statements</h3>
|
|
<p>C++17 modified the <em>condition</em> part of <code>if</code> and
|
|
<code>switch</code> statements, permitting an <em>init-statement</em> to
|
|
be included (<a href="http://wg21.link/p0305r1">p0305r1</a>).</p>
|
|
<p>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.</p>
|
|
<p>This new syntax is in addition to the <em>condition</em> being a
|
|
declaration with a <em>brace-or-equal-initializer</em>. For an
|
|
<code>if</code> statement this new sytax gains that benefit without
|
|
violating the long-standing guidance against using <a
|
|
href="#avoid-implicit-conversions-to-bool">implicit conversions to
|
|
<code>bool</code></a>, which still stands.</p>
|
|
<p>For example, uses of Unified Logging sometimes explicitly check
|
|
whether a <code>LogTarget</code> is enabled. Instead of</p>
|
|
<pre><code> LogTarget(...) lt;
|
|
if (lt.is_enabled()) {
|
|
LogStream log(lt);
|
|
... use log ...
|
|
}
|
|
... lt is accessible but probably not needed here ...</code></pre>
|
|
<p>using this feature one could write</p>
|
|
<pre><code> if (LogTarget(...) lt; lt.is_enabled()) {
|
|
LogStream log(lt);
|
|
... use log ...
|
|
}</code></pre>
|
|
<p>C++17 also added compile-time <code>if</code> statements (<a
|
|
href="http://wg21.link/p0292r2">p0292r2</a>). Use of
|
|
<code>if constexpr</code> is permitted. This feature can replace and
|
|
(sometimes vastly) simplify many uses of <a
|
|
href="https://en.cppreference.com/w/cpp/language/sfinae"
|
|
title="Substitution Failure Is Not An Error">SFINAE</a>. The same
|
|
declaration and initialization guidance for the <em>condition</em> part
|
|
apply here as for ordinary <code>if</code> statements.</p>
|
|
<h3 id="expression-evaluation-order">Expression Evaluation Order</h3>
|
|
<p>C++17 tightened up the evaluation order for some kinds of
|
|
subexpressions (<a href="http://wg21.link/p0138r2">p0138r2</a>). 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.</p>
|
|
<p>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.</p>
|
|
<h3 id="compatibility-with-c11">Compatibility with C11</h3>
|
|
<p>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.</p>
|
|
<p>Note that the C parts of the JDK have been built with C11 selected
|
|
for some time (<a
|
|
href="https://bugs.openjdk.org/browse/JDK-8292008">JDK-8292008</a>).</p>
|
|
<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://wg21.link/n1720">n1720</a>)
|
|
(<a href="http://wg21.link/n3928">n3928</a>)<br> Both the original
|
|
(C++11) two-argument form and the new (C++17) single-argument form are
|
|
permitted.</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>
|
|
<li><p>Preprocessor Condition <code>__has_include</code> (<a
|
|
href="http://wg21.link/p0061r0">p0061r0</a>) (<a
|
|
href="http://wg21.link/p0061r1">p0061r1</a>)</p></li>
|
|
<li><p>Hexadecimal Floating-Point Literals (<a
|
|
href="http://wg21.link/p0245r1">p0245r1</a>)</p></li>
|
|
<li><p>Construction Rules for <code>enum class</code> Values (<a
|
|
href="http://wg21.link/p0138r2">p0138r2</a>)</p></li>
|
|
<li><p>Allow <code>typename</code> in template template parameter (<a
|
|
href="http://wg21.link/n4051">n4051</a>) — template template parameters
|
|
are barely used (if at all) in HotSpot, but there's no reason to
|
|
artificially forbid this syntactic regularization in any such
|
|
uses.</p></li>
|
|
</ul>
|
|
<h2 id="forbidden-features">Forbidden Features</h2>
|
|
<h3 id="structured-bindings">Structured Bindings</h3>
|
|
<p>The use of structured bindings <a
|
|
href="http://wg21.link/p0217r3">p0217r3</a> is forbidden. Preferred
|
|
approaches for handling functions with multiple return values
|
|
include</p>
|
|
<ul>
|
|
<li><p>Return a named class/struct intended for that purpose, with named
|
|
and typed members/accessors.</p></li>
|
|
<li><p>Return a value along with out parameters (usually pointers,
|
|
sometimes references).</p></li>
|
|
<li><p>Designate a sentinel "failure" value in the normal return value
|
|
type, with some out of band location for additional information. For
|
|
example, this is the model typically used with <code>errno</code>, where
|
|
a function returns a normal result, or -1 to indicate an error, with
|
|
additional error information in <code>errno</code>.</p></li>
|
|
</ul>
|
|
<p>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
|
|
<code>std::pair</code> because <code>first</code> and
|
|
<code>second</code> members don't carry any useful information.</p>
|
|
<h3 id="file-system-library">File System Library</h3>
|
|
<p>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.</p>
|
|
<p><a href="http://wg21.link/n4100">n4100</a> <a
|
|
href="http://wg21.link/p0218r0">p0218r0</a> <a
|
|
href="http://wg21.link/p0219r1">p0219r1</a> <a
|
|
href="http://wg21.link/p0317r1">p0317r1</a> <a
|
|
href="http://wg21.link/p0392r0">p0392r0</a> <a
|
|
href="http://wg21.link/p0430r2">p0430r2</a> <a
|
|
href="http://wg21.link/p0492r2">p0492r2</a> <a
|
|
href="http://wg21.link/p1164r1">p1164r1</a></p>
|
|
<h3 id="aggregate-extensions">Aggregate Extensions</h3>
|
|
<p>Aggregates with base classes are forbidden. C++17 allows aggregate
|
|
initialization for classes with base classes (<a
|
|
href="https://wg21.link/p0017r1">p0017r1</a>). HotSpot makes very little
|
|
use of aggregate classes, preferring explicit constructors even for very
|
|
simple classes.</p>
|
|
<h3 id="additional-forbidden-features">Additional Forbidden
|
|
Features</h3>
|
|
<ul>
|
|
<li><p><code><algorithm></code>, <code><iterator></code>,
|
|
<code><numeric></code><br> Not useful without standard containers
|
|
or similar classes in HotSpot.</p></li>
|
|
<li><p><code><bitset></code> - Overlap with HotSpot
|
|
<code>BitMap</code>.</p></li>
|
|
<li><p><code><cassert></code>, <code>assert.h</code> - HotSpot has
|
|
its own <code>assert</code> macro.</p></li>
|
|
<li><p><code><exception></code>, <code><stdexcept></code> -
|
|
Use of <a href="#error-handling">exceptions</a> is not
|
|
permitted.</p></li>
|
|
<li><p>Thread support - <code><thread></code>,
|
|
<code><mutex></code>, <code><shared_mutex></code>,
|
|
<code><condition_varible></code>, <code><future></code><br>
|
|
HotSpot has its own threading support.</p></li>
|
|
<li><p>Streams - HotSpot doesn't use the C++ I/O library.</p></li>
|
|
<li><p><code><scoped_allocator></code> - Not useful without
|
|
specialized allocators.</p></li>
|
|
<li><p><code><string></code> - Requires allocator support, similar
|
|
to standard containers.</p></li>
|
|
<li><p><code><typeinfo></code>, <code><typeindex></code><br>
|
|
Use of <a href="#runtime-type-information">runtime type information</a>
|
|
is not permitted.</p></li>
|
|
<li><p><code><valarray></code> - May allocate, but is not
|
|
allocator-aware.</p></li>
|
|
<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 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. Conversion to <code>bool</code>
|
|
operators aren't needed because of the <a
|
|
href="#avoid-implicit-conversions-to-bool">no implicit boolean</a>
|
|
guideline.)</p></li>
|
|
<li><p>Avoid <code>goto</code> statements.</p></li>
|
|
<li><p>Attributes for namespaces and enumerators (<a
|
|
href="http://wg21.link/n4266">n4266</a> — The only applicable attribute
|
|
is <a href="#attributes"><code>[[deprecated]]</code></a>, which is
|
|
forbidden.</p></li>
|
|
<li><p>Variadic <code>using</code> declarations (<a
|
|
href="http://wg21.link/p0195r2">p0195r2</a>)</p></li>
|
|
<li><p><code>std::variant<></code> (<a
|
|
href="http://wg21.link/p0088r3">p0088r3</a>) — Even if more of the C++
|
|
Standard Library is permitted, this class will remain forbidded. Invalid
|
|
accesses are indicated by throwing exceptions.</p></li>
|
|
<li><p><code>std::any</code> (<a
|
|
href="http://wg21.link/p0220r1">p0220r1</a>) — Even if more of the C++
|
|
Standard Library is permitted, this class will remain forbidden. It may
|
|
require allocation, and always uses the standard allocator. It requires
|
|
<a href="https://en.wikipedia.org/wiki/Run-time_type_information"
|
|
title="Runtime Type Information">RTTI</a>.</p></li>
|
|
<li><p><code>std::as_const()</code> (<a
|
|
href="http://wg21.link/p0007r1">p0007r1</a>) — If sufficiently useful,
|
|
HotSpot could add such a function. It would likely be added to
|
|
globalDefinitions.hpp, where there are already some similar small
|
|
utilities.</p></li>
|
|
<li><p><code>std::clamp()</code> (<a
|
|
href="http://wg21.link/p002501">p002501</a>) — This function is already
|
|
provided in globalDefinitions.hpp.</p></li>
|
|
<li><p>Parallel STL Algorithms (<a
|
|
href="http://wg21.link/p0024r2">p0024r2</a>) — Even if more of the C++
|
|
Standard Library is permitted, these will remain forbidden. They are
|
|
built on the standard C++ threading mechanisms. HotSpot doesn't use
|
|
those mechanisms, instead providing and using its own.</p></li>
|
|
<li><p>Cache Line Sizes <a href="http://wg21.link/p0154r1">p0154r1</a> —
|
|
HotSpot has its own mechanisms for this, using values like
|
|
<code>DEFAULT_CACHE_LINE_SIZE</code>. The platform-specific
|
|
implementation of the HotSpot mechanisms might use these library
|
|
functions, but there is no reason to move away from the current
|
|
approach. Quoting from <a href="https://www.cppstd17.com"
|
|
title="C++17: The Complete Guide">JOSUTTIS</a>: "... if you know better,
|
|
use specific values, but using these values is better than any assumed
|
|
fixed size for code supporting multiple platforms."</p></li>
|
|
<li><p><code>register</code> storage class removal <a
|
|
href="http://wg21.link/p0001r1">p0001r1</a> — The <code>register</code>
|
|
storage class has been removed. <code>register</code> is still a
|
|
keyword, so still can't be used for normal purposes. Also, this doesn't
|
|
affect the use of <code>register</code> for gcc-style extended asm code;
|
|
that's a different syntactic element with a different meaning.</p></li>
|
|
<li><p>Value of <code>__cplusplus</code> — Testing whether
|
|
<code>__cplusplus</code> is defined or not is permitted, and indeed
|
|
required. But the value should not need to be examined. The value is
|
|
changed with each revision of the Standard. But we build HotSpot and
|
|
(most of) the rest of the JDK with a specifically selected version of
|
|
the Standard. The value of <code>__cplusplus</code> should be known and
|
|
unchanging until we change the project's build configuration again. So
|
|
examining the value shouldn't ever be necessary.</p></li>
|
|
<li><p>Removal of <code>++</code> for <code>bool</code> (<a
|
|
href="http://wg21.link/p0003r1">p0003r1</a>)</p></li>
|
|
<li><p>Removal of trigraphs (<a
|
|
href="http://wg21.link/n4086">n4086</a>)</p></li>
|
|
</ul>
|
|
<h2 id="undecided-features">Undecided Features</h2>
|
|
<p>This list is incomplete; it serves to explicitly call out some
|
|
features that have not yet been discussed.</p>
|
|
<p>Some features are undecided (so implicitly forbidden) because we
|
|
don't expect to use them at all. This might be reconsidered if someone
|
|
finds a good use case.</p>
|
|
<p>Some Standard Library features are undecided (so implicitly
|
|
forbidden) because, while this Style Guide forbids the use of such, they
|
|
may be sufficiently useful that we want to permit them anyway. Doing so
|
|
may require some idiomatic mechanism for addressing things like
|
|
<code>assert</code> incompatibility, incompatibility with HotSpot's
|
|
<code>FORBID_C_FUNCTION</code> mechanism, and the like.</p>
|
|
<h3 id="stdoptional">std::optional<></h3>
|
|
<p>It is undecided whether to permit the use of
|
|
<code>std::optional<></code> (<a
|
|
href="http://wg21.link/p0220r1">p0220r1</a>). It may be sufficiently
|
|
useful that it should be permitted despite the usual prohibition against
|
|
using Standard Library facilities. Use of the <code>value()</code>
|
|
member function must be forbidden, as it reports an invalid access by
|
|
throwing an exception.</p>
|
|
<h3 id="stdbyte">std::byte</h3>
|
|
<p>It is undecided whether to permit the use of the
|
|
<code>std::byte</code> type (<a
|
|
href="http://wg21.link/p0298r3">p0298r3</a>). It may be sufficiently
|
|
useful that it should be permitted despite the usual prohibition against
|
|
using Standard Library facilities.</p>
|
|
<p>It has been suggested that changing the HotSpot <code>address</code>
|
|
type to use <code>std::byte</code> has some benefits. That is,
|
|
replace</p>
|
|
<pre><code>typedef u_char* address;
|
|
typedef const u_char* const_address;</code></pre>
|
|
<pre><code>using address = std::byte*;
|
|
using const_address = const std::byte*;</code></pre>
|
|
<p>in globalDefinitions.hpp.</p>
|
|
<p>A specific benefit that was mentioned is that it might improve the
|
|
horrible way that gdb handles our current definition of the
|
|
<code>address</code> type.</p>
|
|
<pre><code>#include <cstddef>
|
|
|
|
typedef unsigned char* address;
|
|
typedef std::byte* address_b;
|
|
|
|
int main() {
|
|
|
|
char* mem;
|
|
|
|
address addr = (address)mem;
|
|
address_b addr_b = (address_b)mem;
|
|
|
|
return 0;
|
|
}</code></pre>
|
|
<pre><code>(gdb) p addr
|
|
$1 = (address) 0x7ffff7fe4fa0 <dl_main> "\363\017\036\372Uf\017\357\300H\211\345AWI\211\377AVAUATSH\201\354\210\002"
|
|
(gdb) p addr_b
|
|
$2 = (address_b) 0x7ffff7fe4fa0 <dl_main></code></pre>
|
|
<p>This needs to be explored. Some folks have said they will do so.</p>
|
|
<h3 id="string-views">String Views</h3>
|
|
<p>It is undecided whether to permit the use of
|
|
<code>std::string_view</code> (<a
|
|
href="http://wg21.link/p0220r1">p0220r1</a>).</p>
|
|
<p>HotSpot doesn't use <code>std::string</code>, but uses
|
|
<code>char*</code> strings a lot. Wrapping such in a
|
|
<code>std::string_view</code> to enable the use of various algorithms
|
|
could be useful. But since HotSpot also doesn't permit use of
|
|
<code><algorithm></code> and the like, that only gets the limited
|
|
set of algorithms provided by the view class directly.</p>
|
|
<p>There is also the issue of <code>NUL</code> termination; string views
|
|
are not necessarily <code>NUL</code> terminated. Moreover, if one goes
|
|
to the work of making one that is <code>NUL</code> terminated, that
|
|
terminator is included in the size.</p>
|
|
<p>There are other caveats. Permitting use of string views would require
|
|
discussion of those.</p>
|
|
<h3 id="substring-and-subsequence-searching">Substring and Subsequence
|
|
Searching</h3>
|
|
<p>In addition to simple substring searching, the Standard Library now
|
|
includes Boyer-Moore and Boyer-Moore-Horspool searchers, in case someone
|
|
wants to search really large texts. That seems an unlikely use-case for
|
|
HotSpot. See <a href="http://wg21.link/p0220r1">p0220r1</a>.</p>
|
|
<h3 id="new-and-delete-with-over-aligned-data"><code>new</code> and
|
|
<code>delete</code> with Over-Aligned Data</h3>
|
|
<p>It is undecided whether to permit the use of dynamic allocation of
|
|
overaligned types (<a href="http://wg21.link/n3396">n3396</a>).</p>
|
|
<p>HotSpot currently only has a couple of over-aligned types that are
|
|
dynamically allocated. These are handled manually, not going through
|
|
<code>new</code> expressions, as that couldn't work before C++17.</p>
|
|
<p>One of the ways an over-aligned type might arise is by aligning a
|
|
data member. This might be done to avoid destructive interference for
|
|
concurrent accesses. But HotSpot uses a different approach, using
|
|
explicit padding. Again, this is in part because <code>new</code> and
|
|
<code>delete</code> of overaligned types didn't work. But we might
|
|
prefer to continue this approach.</p>
|
|
<p>We would need to add <code>operator new</code> overloads to
|
|
<code>CHeapObj<></code> and possibly in other places in order to
|
|
support this. However, it has been suggested that implementing it
|
|
(efficiently) on top of NMT might be difficult. Note that
|
|
<code>posix_memalign</code> / <code>_aligned_malloc</code> don't help
|
|
here, because of NMT's use of malloc headers.</p>
|
|
<p>If we don't support it we may want to add <code>operator new</code>
|
|
overloads that are deleted, to prevent attempted uses.</p>
|
|
<p>Alignment usage in non-HotSpot parts of the OpenJDK:</p>
|
|
<ul>
|
|
<li><p><code>alignas</code> used once in harfbuzz, to align a
|
|
variable.</p></li>
|
|
<li><p>libpipewire has <code>#define SPA_ALIGNED</code> macro using gcc
|
|
<code>aligned</code> attribute, but doesn't use it.</p></li>
|
|
<li><p>libsleef has <code>#define ALIGNED</code> macro using gcc
|
|
<code>aligned</code> attribute. It is not used for class or member
|
|
declarations.</p></li>
|
|
</ul>
|
|
<h3 id="stdto_chars-and-stdfrom_chars"><code>std::to_chars()</code> and
|
|
<code>std::from_chars</code></h3>
|
|
<p>It is undecided whether to permit the use of
|
|
<code>std::to_chars()</code> and <code>std::from_chars()</code> (<a
|
|
href="http://wg21.link/p0067r5">p0067r5</a>).</p>
|
|
<p>These functions provide low-level conversions between character
|
|
sequences and numeric values. This seems like a good candidate for use
|
|
in HotSpot, potentially replacing various clumsy or less performant
|
|
alternatives. There is no memory allocation. Parsing failures are
|
|
indicated via error codes rather than exceptions. Various other nice for
|
|
HotSpot properties.</p>
|
|
<p>Note that the published C++17 Standard puts these in
|
|
<code><utility></code>, but a defect report moved them to
|
|
<code><charconv></code>. This also needs
|
|
<code><system_error></code>.</p>
|
|
<p>This would require upgrading the minimum gcc version to 11.1 for
|
|
floating point conversion support. The minimum Visual Studio version is
|
|
already sufficient. The minimum clang version requirement hasn't been
|
|
determined yet.</p>
|
|
<h3 id="stdlaunder"><code>std::launder()</code></h3>
|
|
<p>It is undecided whether to permit the use of
|
|
<code>std::launder()</code> (<a
|
|
href="http://wg21.link/p0137r1">p0137r1</a>).</p>
|
|
<p>Change to permitted if we discover a place where we need it. Or maybe
|
|
we should just permit it, but hope we don't need it.</p>
|
|
<p>Also, C++20 revised the relevant part of Object Lifetime in a way
|
|
that seems more permissive and with less need of laundering. We don't
|
|
know if implementations of prior versions take advantage of the
|
|
difference.</p>
|
|
<p>See Object Lifetime: C++17 6.8/8, C++20 6.7.3/8</p>
|
|
<h3 id="additional-undecided-features">Additional Undecided
|
|
Features</h3>
|
|
<ul>
|
|
<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>
|
|
<li><p>Shorthand for nested namespaces (<a
|
|
href="http://wg21.link/n4230">n4230</a>) — HotSpot makes very little use
|
|
of namespaces, so this seemingly innocuous feature probably isn't useful
|
|
to us.</p></li>
|
|
<li><p>Direct list initialization with <code>auto</code> (<a
|
|
href="http://wg21.link/n3681">n3681</a>) — This change fixed some issues
|
|
with direct list initialization and <code>auto</code>. But we don't use
|
|
that feature much, if at all. And perhaps shouldn't be using
|
|
it.</p></li>
|
|
<li><p>UTF-8 Character Literals (<a
|
|
href="http://wg21.link/n4267">n4267</a>) — Do we have a use-case for
|
|
this?</p></li>
|
|
<li><p>Fold Expressions (<a href="http://wg21.link/n4295">n4295</a>) —
|
|
Provides a simple way to apply operators to a parameter pack. HotSpot
|
|
doesn't use variadic templates very much. That makes it questionable
|
|
that developers should need to know about this feature. But if someone
|
|
does come up with a good use-case, it's likely that the alternatives are
|
|
significantly worse, because pack manipulation without this can be
|
|
complicated.</p></li>
|
|
<li><p><a
|
|
href="https://en.cppreference.com/w/cpp/header/tuple.html"><code><tuple></code></a>
|
|
— Prefer named access to class objects, rather than indexed access to
|
|
anonymous heterogeneous sequences. In particular, a standard-layout
|
|
class is preferred to a tuple.</p></li>
|
|
<li><p><code>std::invoke<>()</code> (<a
|
|
href="http://wg21.link/n4169">n4169</a>)</p></li>
|
|
<li><p><a
|
|
href="https://en.cppreference.com/w/cpp/header/chrono.html"><code><chrono></code></a>
|
|
— The argument for chrono is that our existing APIs aren't serving us
|
|
well. chrono provides strong type safety. We've had multiple cases of
|
|
mistakes like a double seconds being treated as double milliseconds or
|
|
vice versa, and other similar errors. But it would be a large effort to
|
|
adopt chrono. We'd also need to decide whether to use the predefined
|
|
clocks or hook up chrono to our clocks. It may be that using the
|
|
predefined clocks is fine, but it's a question that needs careful
|
|
study.</p></li>
|
|
<li><p><a
|
|
href="https://en.cppreference.com/w/cpp/header/initializer_list.html"><code><initializer_list></code></a>
|
|
— The potential ambiguity between some forms of direct initialization
|
|
and initializer list initialization, and the resolution of that
|
|
ambiguity, is unfortunate.</p></li>
|
|
<li><p><a
|
|
href="https://en.cppreference.com/w/cpp/header/ratio.html"><code><ratio></code></a>
|
|
— <code><ratio></code> is a <em>compile-time</em> rational
|
|
arithmetic package. It's also fixed (though parameterized) precision.
|
|
It's not a general purpose rational arithmetic facility. It appears to
|
|
have started out as an implementation detail of chrono, and was
|
|
extracted and promoted to a public facility in the belief that it has
|
|
broader utility.</p></li>
|
|
<li><p><a
|
|
href="https://en.cppreference.com/w/cpp/header/system_error.html"><code><system_error></code></a>
|
|
— We don't really have a generally agreed upon mechanism for managing
|
|
errors. Instead, we have a plethora of bespoke ad hoc mechanisms.
|
|
Managing errors is a topic of substantial discussion.
|
|
<code><system_error></code> might end up being a part of a result
|
|
from that discussion.</p></li>
|
|
</ul>
|
|
</body>
|
|
</html>
|