2020-07-28 02:19:33 +00:00
|
|
|
<!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>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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;}
|
2020-07-28 02:19:33 +00:00
|
|
|
</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>
|
2022-11-21 18:32:40 +00:00
|
|
|
<nav id="TOC" role="doc-toc">
|
|
|
|
<ul>
|
|
|
|
<li><a href="#introduction" id="toc-introduction">Introduction</a>
|
2020-07-28 02:19:33 +00:00
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><a href="#why-care-about-style" id="toc-why-care-about-style">Why
|
|
|
|
Care About Style?</a></li>
|
|
|
|
<li><a href="#counterexamples-and-updates"
|
|
|
|
id="toc-counterexamples-and-updates">Counterexamples and
|
|
|
|
Updates</a></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><a href="#structure-and-formatting"
|
|
|
|
id="toc-structure-and-formatting">Structure and Formatting</a>
|
|
|
|
<ul>
|
|
|
|
<li><a href="#factoring-and-class-design"
|
|
|
|
id="toc-factoring-and-class-design">Factoring and Class Design</a></li>
|
|
|
|
<li><a href="#source-files" id="toc-source-files">Source Files</a></li>
|
|
|
|
<li><a href="#jtreg-tests" id="toc-jtreg-tests">JTReg Tests</a></li>
|
|
|
|
<li><a href="#naming" id="toc-naming">Naming</a></li>
|
|
|
|
<li><a href="#commenting" id="toc-commenting">Commenting</a></li>
|
|
|
|
<li><a href="#macros" id="toc-macros">Macros</a></li>
|
|
|
|
<li><a href="#whitespace" id="toc-whitespace">Whitespace</a></li>
|
|
|
|
<li><a href="#miscellaneous"
|
|
|
|
id="toc-miscellaneous">Miscellaneous</a></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><a href="#use-of-c-features" id="toc-use-of-c-features">Use of C++
|
|
|
|
Features</a>
|
|
|
|
<ul>
|
|
|
|
<li><a href="#error-handling" id="toc-error-handling">Error
|
|
|
|
Handling</a></li>
|
|
|
|
<li><a href="#rtti-runtime-type-information"
|
|
|
|
id="toc-rtti-runtime-type-information">RTTI (Runtime Type
|
|
|
|
Information)</a></li>
|
|
|
|
<li><a href="#memory-allocation" id="toc-memory-allocation">Memory
|
|
|
|
Allocation</a></li>
|
|
|
|
<li><a href="#class-inheritance" id="toc-class-inheritance">Class
|
|
|
|
Inheritance</a></li>
|
|
|
|
<li><a href="#namespaces" id="toc-namespaces">Namespaces</a></li>
|
|
|
|
<li><a href="#c-standard-library" id="toc-c-standard-library">C++
|
|
|
|
Standard Library</a></li>
|
|
|
|
<li><a href="#type-deduction" id="toc-type-deduction">Type
|
|
|
|
Deduction</a></li>
|
|
|
|
<li><a href="#expression-sfinae" id="toc-expression-sfinae">Expression
|
|
|
|
SFINAE</a></li>
|
|
|
|
<li><a href="#enum" id="toc-enum">enum</a></li>
|
2022-12-15 19:38:39 +00:00
|
|
|
<li><a href="#alignas" id="toc-alignas">alignas</a></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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="#uniform-initialization"
|
|
|
|
id="toc-uniform-initialization">Uniform Initialization</a></li>
|
|
|
|
<li><a href="#local-function-objects"
|
|
|
|
id="toc-local-function-objects">Local Function Objects</a></li>
|
|
|
|
<li><a href="#inheriting-constructors"
|
|
|
|
id="toc-inheriting-constructors">Inheriting constructors</a></li>
|
2023-02-28 01:59:03 +00:00
|
|
|
<li><a href="#attributes" id="toc-attributes">Attributes</a></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><a href="#additional-permitted-features"
|
|
|
|
id="toc-additional-permitted-features">Additional Permitted
|
|
|
|
Features</a></li>
|
|
|
|
<li><a href="#excluded-features" id="toc-excluded-features">Excluded
|
|
|
|
Features</a></li>
|
|
|
|
<li><a href="#undecided-features" id="toc-undecided-features">Undecided
|
|
|
|
Features</a></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul></li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
|
|
<h2 id="introduction">Introduction</h2>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="why-care-about-style">Why Care About Style?</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="counterexamples-and-updates">Counterexamples and Updates</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>Many of the guidelines mentioned here have (sometimes widespread)
|
|
|
|
counterexamples in the HotSpot code base. Finding a counterexample is
|
|
|
|
not sufficient justification for new code to follow the counterexample
|
|
|
|
as a precedent, since readers of your code will rightfully expect your
|
|
|
|
code to follow the greater bulk of precedents documented here.</p>
|
|
|
|
<p>Occasionally a guideline mentioned here may be just out of synch with
|
|
|
|
the actual HotSpot code base. If you find that a guideline is
|
|
|
|
consistently contradicted by a large number of counterexamples, please
|
|
|
|
bring it up for discussion and possible change. The architectural rule,
|
|
|
|
of course, is "When in Rome do as the Romans". Sometimes in the suburbs
|
|
|
|
of Rome the rules are a little different; these differences can be
|
|
|
|
pointed out here.</p>
|
|
|
|
<p>Proposed changes should be discussed on the <a
|
|
|
|
href="mailto:hotspot-dev@openjdk.org">HotSpot Developers</a> mailing
|
|
|
|
list. Changes are likely to be cautious and incremental, since HotSpot
|
|
|
|
coders have been using these guidelines for years.</p>
|
|
|
|
<p>Substantive changes are approved by <a
|
|
|
|
href="https://www.rfc-editor.org/rfc/rfc7282.html">rough consensus</a>
|
|
|
|
of the <a href="https://openjdk.org/census#hotspot">HotSpot Group</a>
|
|
|
|
Members. The Group Lead determines whether consensus has been
|
|
|
|
reached.</p>
|
|
|
|
<p>Editorial changes (changes that only affect the description of
|
|
|
|
HotSpot style, not its substance) do not require the full consensus
|
|
|
|
gathering process. The normal HotSpot pull request process may be used
|
|
|
|
for editorial changes, with the additional requirement that the
|
|
|
|
requisite reviewers are also HotSpot Group Members.</p>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h2 id="structure-and-formatting">Structure and Formatting</h2>
|
|
|
|
<h3 id="factoring-and-class-design">Factoring and Class Design</h3>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
2020-08-19 10:11:15 +00:00
|
|
|
<h3 id="source-files">Source Files</h3>
|
2020-07-28 02:19:33 +00:00
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p>All source files must have a globally unique basename. The build
|
|
|
|
system depends on this uniqueness.</p></li>
|
|
|
|
<li><p>Do not put non-trivial function implementations in .hpp files. If
|
|
|
|
the implementation depends on other .hpp files, put it in a .cpp or a
|
|
|
|
.inline.hpp file.</p></li>
|
|
|
|
<li><p>.inline.hpp files should only be included in .cpp or .inline.hpp
|
|
|
|
files.</p></li>
|
|
|
|
<li><p>All .inline.hpp files should include their corresponding .hpp
|
|
|
|
file as the first include line. Declarations needed by other files
|
|
|
|
should be put in the .hpp file, and not in the .inline.hpp file. This
|
|
|
|
rule exists to resolve problems with circular dependencies between
|
|
|
|
.inline.hpp files.</p></li>
|
|
|
|
<li><p>All .cpp files include precompiled.hpp as the first include
|
|
|
|
line.</p></li>
|
|
|
|
<li><p>precompiled.hpp is just a build time optimization, so don't rely
|
|
|
|
on it to resolve include problems.</p></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
<li><p>Keep the include lines alphabetically sorted.</p></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p>Put conditional inclusions (<code>#if ...</code>) at the end of
|
|
|
|
the include list.</p></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
2020-08-19 10:11:15 +00:00
|
|
|
<h3 id="jtreg-tests">JTReg Tests</h3>
|
|
|
|
<ul>
|
|
|
|
<li><p>JTReg tests should have meaningful names.</p></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-08-19 10:11:15 +00:00
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-08-19 10:11:15 +00:00
|
|
|
</ul></li>
|
|
|
|
</ul>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="naming">Naming</h3>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</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>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
|
|
|
<h3 id="macros">Macros</h3>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
|
|
|
<h3 id="whitespace">Whitespace</h3>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<li><p>Indentation levels are two columns.</p></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<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>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
|
|
|
<h3 id="miscellaneous">Miscellaneous</h3>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p>Use the <a href="https://en.cppreference.com/w/cpp/language/raii"
|
|
|
|
title="Resource Acquisition Is Initialization">Resource Acquisition Is
|
|
|
|
Initialization</a> (RAII) design pattern to manage bracketed critical
|
|
|
|
sections. See class <code>ResourceMark</code> for an example.</p></li>
|
|
|
|
<li><p>Avoid implicit conversions to <code>bool</code>.</p>
|
2020-07-28 02:19:33 +00:00
|
|
|
<ul>
|
|
|
|
<li>Use <code>bool</code> for boolean values.</li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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 declarations in <em>condition</em> forms, i.e. don't use
|
|
|
|
<code>if (T v = value) { ... }</code>.</li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<li><p>Use arrays with abstractions supporting range checks.</p></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
|
|
|
<h2 id="use-of-c-features">Use of C++ Features</h2>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>HotSpot was originally written in a subset of the C++98/03 language.
|
|
|
|
More recently, support for C++14 is provided, though again, HotSpot only
|
|
|
|
uses a subset. (Backports to JDK versions lacking support for more
|
|
|
|
recent Standards must of course stick with the original C++98/03
|
|
|
|
subset.)</p>
|
|
|
|
<p>This section describes that subset. Features from the C++98/03
|
|
|
|
language may be used unless explicitly excluded here. Features from
|
|
|
|
C++11 and C++14 may be explicitly permitted or explicitly excluded, and
|
|
|
|
discussed accordingly here. There is a third category, undecided
|
|
|
|
features, about which HotSpot developers have not yet reached a
|
|
|
|
consensus, or perhaps have not discussed at all. Use of these features
|
|
|
|
is also excluded.</p>
|
|
|
|
<p>(The use of some features may not be immediately obvious and may slip
|
|
|
|
in anyway, since the compiler will accept them. The code review process
|
|
|
|
is the main defense against this.)</p>
|
|
|
|
<p>Some features are discussed in their own subsection, typically to
|
|
|
|
provide more extensive discussion or rationale for limitations. Features
|
|
|
|
that don't have their own subsection are listed in omnibus feature
|
|
|
|
sections for permitted, excluded, and undecided features.</p>
|
|
|
|
<p>Lists of new features for C++11 and C++14, along with links to their
|
|
|
|
descriptions, can be found in the online documentation for some of the
|
|
|
|
compilers and libraries. The C++14 Standard is the definitive
|
|
|
|
description.</p>
|
|
|
|
<ul>
|
|
|
|
<li><a href="https://gcc.gnu.org/projects/cxx-status.html">C++ Standards
|
|
|
|
Support in GCC</a></li>
|
|
|
|
<li><a href="https://clang.llvm.org/cxx_status.html">C++ Support in
|
|
|
|
Clang</a></li>
|
|
|
|
<li><a
|
|
|
|
href="https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance">Visual
|
|
|
|
C++ Language Conformance</a></li>
|
|
|
|
<li><a
|
|
|
|
href="https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html">libstdc++
|
|
|
|
Status</a></li>
|
|
|
|
<li><a href="https://libcxx.llvm.org/cxx1y_status.html">libc++
|
|
|
|
Status</a></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>As a rule of thumb, permitting features which simplify writing code
|
|
|
|
and, especially, reading code, is encouraged.</p>
|
2020-07-28 02:19:33 +00:00
|
|
|
<p>Similar discussions for some other projects:</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
|
|
|
<h3 id="error-handling">Error Handling</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="memory-allocation">Memory Allocation</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>Do not use the standard global allocation and deallocation functions
|
|
|
|
(operator new and related functions). Use of these functions by HotSpot
|
|
|
|
code is disabled for some platforms.</p>
|
|
|
|
<p>Rationale: HotSpot often uses "resource" or "arena" allocation. Even
|
|
|
|
where heap allocation is used, the standard global functions are avoided
|
|
|
|
in favor of wrappers around malloc and free that support the VM's Native
|
|
|
|
Memory Tracking (NMT) feature. Typically, uses of the global operator
|
|
|
|
new are inadvertent and therefore often associated with memory
|
|
|
|
leaks.</p>
|
|
|
|
<p>Native memory allocation failures are often treated as
|
|
|
|
non-recoverable. The place where "out of memory" is (first) detected may
|
|
|
|
be an innocent bystander, unrelated to the actual culprit.</p>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="class-inheritance">Class Inheritance</h3>
|
|
|
|
<p>Use public single inheritance.</p>
|
|
|
|
<p>Prefer composition rather than non-public inheritance.</p>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>Restrict inheritance to the "is-a" case; use composition rather than
|
|
|
|
non-is-a related inheritance.</p>
|
2020-07-28 02:19:33 +00:00
|
|
|
<p>Avoid multiple inheritance. Never use virtual inheritance.</p>
|
|
|
|
<h3 id="namespaces">Namespaces</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<p>Benefits of using such classes include:</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="c-standard-library">C++ Standard Library</h3>
|
|
|
|
<p>Avoid using the C++ Standard Library.</p>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<p>Some reasons for this include</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p>Exceptions. Perhaps the largest core issue with adopting the use
|
|
|
|
of Standard Library facilities is exceptions. HotSpot does not use
|
|
|
|
exceptions and, for platforms which allow doing so, builds with them
|
|
|
|
turned off. Many Standard Library facilities implicitly or explicitly
|
|
|
|
use exceptions.</p></li>
|
|
|
|
<li><p><code>assert</code>. An issue that is quickly encountered is the
|
|
|
|
<code>assert</code> macro name collision (<a
|
|
|
|
href="https://bugs.openjdk.org/browse/JDK-8007770">JDK-8007770</a>).
|
|
|
|
Some mechanism for addressing this would be needed before much of the
|
|
|
|
Standard Library could be used. (Not all Standard Library
|
|
|
|
implementations use assert in header files, but some do.)</p></li>
|
|
|
|
<li><p>Memory allocation. HotSpot requires explicit control over where
|
|
|
|
allocations occur. The C++98/03 <code>std::allocator</code> class is too
|
|
|
|
limited to support our usage. (Changes in more recent Standards may
|
|
|
|
remove this limitation.)</p></li>
|
|
|
|
<li><p>Implementation vagaries. Bugs, or simply different implementation
|
|
|
|
choices, can lead to different behaviors among the various Standard
|
|
|
|
Libraries we need to deal with.</p></li>
|
|
|
|
<li><p>Inconsistent naming conventions. HotSpot and the C++ Standard use
|
|
|
|
different naming conventions. The coexistence of those different
|
|
|
|
conventions might appear jarring and reduce readability.</p></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
|
|
|
<p>There are a few exceptions to this rule.</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><code>#include <new></code> to use placement <code>new</code>,
|
|
|
|
<code>std::nothrow</code>, and <code>std::nothrow_t</code>.</li>
|
|
|
|
<li><code>#include <limits></code> to use
|
|
|
|
<code>std::numeric_limits</code>.</li>
|
2023-03-11 14:36:56 +00:00
|
|
|
<li><code>#include <type_traits></code> with some restrictions,
|
|
|
|
listed below.</li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><code>#include <cstddef></code> to use
|
2022-12-15 19:38:39 +00:00
|
|
|
<code>std::nullptr_t</code> and <code>std::max_align_t</code>.</li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
2023-03-11 14:36:56 +00:00
|
|
|
<p>Certain restrictions apply to the declarations provided by
|
|
|
|
<code><type_traits></code>.</p>
|
|
|
|
<ul>
|
|
|
|
<li>The <code>alignof</code> operator should be used rather than
|
|
|
|
<code>std::alignment_of<></code>.</li>
|
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>TODO: Rather than directly #including (permitted) Standard Library
|
|
|
|
headers, use a convention of #including wrapper headers (in some
|
|
|
|
location like hotspot/shared/stdcpp). This provides a single place for
|
|
|
|
dealing with issues we might have for any given header, esp.
|
|
|
|
platform-specific issues.</p>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="type-deduction">Type Deduction</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<p>There are several contexts where types are deduced.</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p>Function argument deduction. This is always permitted, and indeed
|
|
|
|
encouraged. It is nearly always better to allow the type of a function
|
|
|
|
template argument to be deduced rather than explicitly
|
|
|
|
specified.</p></li>
|
|
|
|
<li><p><code>auto</code> variable declarations (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf">n1984</a>)<br>
|
|
|
|
For local variables, this can be used to make the code clearer by
|
|
|
|
eliminating type information that is obvious or irrelevant. Excessive
|
|
|
|
use can make code much harder to understand.</p></li>
|
|
|
|
<li><p>Function return type deduction (<a
|
|
|
|
href="https://isocpp.org/files/papers/N3638.html">n3638</a>)<br> Only
|
|
|
|
use if the function body has a very small number of <code>return</code>
|
|
|
|
statements, and generally relatively little other code.</p></li>
|
|
|
|
<li><p>Also see <a href="#lambdaexpressions">lambda
|
|
|
|
expressions</a>.</p></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
|
|
|
<h3 id="expression-sfinae">Expression SFINAE</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="enum">enum</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2022-12-15 19:38:39 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="thread_local">thread_local</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="nullptr">nullptr</h3>
|
2024-03-06 22:42:18 +00:00
|
|
|
<p>Use <code>nullptr</code> (<a
|
2022-11-21 18:32:40 +00:00
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf">n2431</a>)
|
2024-03-06 22:42:18 +00:00
|
|
|
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>
|
2020-07-28 02:19:33 +00:00
|
|
|
<h3 id="atomic"><atomic></h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-11-17 03:16:10 +00:00
|
|
|
<h3 id="uniform-initialization">Uniform Initialization</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-11-17 03:16:10 +00:00
|
|
|
<p>Some relevant sections from cppreference.com:</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-11-17 03:16:10 +00:00
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
<h3 id="local-function-objects">Local Function Objects</h3>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li>Local function objects, including lambda expressions, may be
|
|
|
|
used.</li>
|
2021-09-28 05:56:34 +00:00
|
|
|
<li>Lambda expressions must only be used as a downward value.</li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
<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>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li>Anonymous lambda expressions should not overly clutter the enclosing
|
|
|
|
expression.</li>
|
2021-09-28 05:56:34 +00:00
|
|
|
<li>An anonymous lambda expression must not be directly invoked.</li>
|
|
|
|
<li>Bind expressions are forbidden.</li>
|
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
<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>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>HotSpot code has historically usually placed the DoSomething class at
|
|
|
|
namespace (or sometimes class) scope. This separates the function's code
|
|
|
|
from its use, often to the detriment of readability. It requires giving
|
|
|
|
the class a globally unique name (if at namespace scope). It also loses
|
|
|
|
the information that the class is intended for use in exactly one place,
|
|
|
|
and does not have any subclasses. (However, the latter can now be
|
|
|
|
indicated by declaring it <code>final</code>.) Often, for simplicity, a
|
|
|
|
local class will skip things like access control and accessor functions,
|
|
|
|
giving the enclosing function direct access to the implementation and
|
|
|
|
eliminating some boilerplate that might be provided if the class is in
|
|
|
|
some outer (more accessible) scope. On the other hand, if there is a lot
|
|
|
|
of surrounding code in the function body or the local class is of
|
|
|
|
significant size, defining it locally can increase clutter and reduce
|
|
|
|
readability.</p>
|
|
|
|
<p><a name="lambdaexpressions"></a> C++11 added <em>lambda
|
|
|
|
expressions</em> as a new way to write a function object. Simple lambda
|
|
|
|
expressions can be significantly more concise than a function object,
|
|
|
|
eliminating a lot of boiler-plate. On the other hand, a complex lambda
|
|
|
|
expression may not provide much, if any, readability benefit compared to
|
|
|
|
an ordinary function object. Also, while a lambda can encapsulate a call
|
|
|
|
to a "function-like" object, it cannot be used in place of such.</p>
|
|
|
|
<p>A common use for local functions is as one-use <a
|
|
|
|
href="https://en.cppreference.com/w/cpp/language/raii"
|
|
|
|
title="Resource Acquisition Is Initialization">RAII</a> objects. The
|
|
|
|
amount of boilerplate for a function object class (local or not) makes
|
|
|
|
such usage somewhat clumsy and verbose. But with the help of a small
|
|
|
|
amount of supporting utility code, lambdas work particularly well for
|
|
|
|
this use case.</p>
|
|
|
|
<p>Another use for local functions is <a
|
|
|
|
href="https://en.wikipedia.org/wiki/Partial_application"
|
|
|
|
title="Partial Application">partial application</a>. Again here, lambdas
|
|
|
|
are typically much simpler and less verbose than function object
|
|
|
|
classes.</p>
|
|
|
|
<p>Because of these benefits, lambda expressions are permitted in
|
|
|
|
HotSpot code, with some restrictions and usage guidance. An anonymous
|
|
|
|
lambda is one which is passed directly as an argument. A named lambda is
|
|
|
|
the value of a variable, which is its name.</p>
|
|
|
|
<p>Lambda expressions should only be passed downward. In particular, a
|
|
|
|
lambda should not be returned from a function or stored in a global
|
|
|
|
variable, whether directly or as the value of a member of some other
|
|
|
|
object. Lambda capture is syntactically subtle (by design), and
|
|
|
|
propagating a lambda in such ways can easily pass references to captured
|
|
|
|
values to places where they are no longer valid. In particular, members
|
|
|
|
of the enclosing <code>this</code> object are effectively captured by
|
|
|
|
reference, even if the default capture is by-value. For such uses-cases
|
|
|
|
a function object class should be used to make the desired value
|
|
|
|
capturing and propagation explicit.</p>
|
|
|
|
<p>Limiting the capture list to <code>[&]</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>
|
2021-09-28 05:56:34 +00:00
|
|
|
</ul></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>The use of <code>mutable</code> lambda expressions is forbidden
|
|
|
|
because there don't seem to be many, if any, good use-cases for them in
|
|
|
|
HotSpot. A lambda expression needs to be mutable in order to modify a
|
|
|
|
by-value captured value. But with only downward lambdas, such usage
|
|
|
|
seems likely to be rare and complicated. It is better to use a function
|
|
|
|
object class in any such cases that arise, rather than requiring all
|
|
|
|
HotSpot developers to understand this relatively obscure feature.</p>
|
|
|
|
<p>While it is possible to directly invoke an anonymous lambda
|
|
|
|
expression, that feature should not be used, as such a form can be
|
|
|
|
confusing to readers. Instead, name the lambda and call it by name.</p>
|
|
|
|
<p>Some reasons to prefer a named lambda instead of an anonymous lambda
|
|
|
|
are</p>
|
2021-09-28 05:56:34 +00:00
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
<li><p>It has an unusual capture list.</p></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p>It has a complex explicit return type or parameter
|
|
|
|
types.</p></li>
|
2021-09-28 05:56:34 +00:00
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
<p>Some examples:</p>
|
|
|
|
<ol type="1">
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
<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>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
<pre><code>c.do_entries(do_entry);</code></pre>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
<p>References:</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
</ul>
|
|
|
|
<p>References from C++17</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
</ul>
|
|
|
|
<p>References from C++20</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2021-09-28 05:56:34 +00:00
|
|
|
</ul>
|
|
|
|
<p>References from C++23</p>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li>Make () more optional for lambdas (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1102r2.html">p1102r2</a>)</li>
|
2021-09-28 05:56:34 +00:00
|
|
|
</ul>
|
2022-03-26 21:46:22 +00:00
|
|
|
<h3 id="inheriting-constructors">Inheriting constructors</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>Do not use <em>inheriting constructors</em> (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm">n2540</a>).</p>
|
|
|
|
<p>C++11 provides simple syntax allowing a class to inherit the
|
|
|
|
constructors of a base class. Unfortunately there are a number of
|
|
|
|
problems with the original specification, and C++17 contains significant
|
|
|
|
revisions (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html"
|
|
|
|
title="p0136r1">p0136r1</a> opens with a list of 8 Core Issues). Since
|
|
|
|
HotSpot doesn't support use of C++17, use of inherited constructors
|
|
|
|
could run into those problems. Such uses might also change behavior in a
|
|
|
|
future HotSpot update to use C++17 or later, potentially in subtle ways
|
|
|
|
that could lead to hard to diagnose problems. Because of this, HotSpot
|
|
|
|
code must not use inherited constructors.</p>
|
|
|
|
<p>Note that gcc7 provides the <code>-fnew-inheriting-ctors</code>
|
|
|
|
option to use the <a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html"
|
|
|
|
title="p0136r1">p0136r1</a> semantics. This is enabled by default when
|
|
|
|
using C++17 or later. It is also enabled by default for
|
|
|
|
<code>fabi-version=11</code> (introduced by gcc7) or higher when using
|
|
|
|
C++11/14, as the change is considered a Defect Report that applies to
|
|
|
|
those versions. Earlier versions of gcc don't have that option, and
|
|
|
|
other supported compilers may not have anything similar.</p>
|
2023-02-28 01:59:03 +00:00
|
|
|
<h3 id="attributes">Attributes</h3>
|
|
|
|
<p>The use of some attributes (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf">n2761</a>)
|
|
|
|
(listed below) is permitted. (Note that some of the attributes defined
|
|
|
|
in that paper didn't make it into the final specification.)</p>
|
|
|
|
<p>Attributes are syntactically permitted in a broad set of locations,
|
|
|
|
but specific attributes are only permitted in a subset of those
|
|
|
|
locations. In some cases an attribute that appertains to a given element
|
|
|
|
may be placed in any of several locations with the same meaning. In
|
|
|
|
those cases HotSpot has a preferred location.</p>
|
|
|
|
<ul>
|
|
|
|
<li>An attribute that appertains to a function is placed at the
|
|
|
|
beginning of the function's declaration, rather than between the
|
|
|
|
function name and the parameter list.</li>
|
|
|
|
</ul>
|
|
|
|
<p>Only the following attributes are permitted:</p>
|
|
|
|
<ul>
|
|
|
|
<li><code>[[noreturn]]</code></li>
|
|
|
|
</ul>
|
|
|
|
<p>The following attributes are expressly forbidden:</p>
|
|
|
|
<ul>
|
|
|
|
<li><code>[[carries_dependency]]</code> - Related to
|
|
|
|
<code>memory_order_consume</code>.</li>
|
|
|
|
<li><code>[[deprecated]]</code> - Not relevant in HotSpot code.</li>
|
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<h3 id="additional-permitted-features">Additional Permitted
|
|
|
|
Features</h3>
|
|
|
|
<ul>
|
2023-03-11 14:36:56 +00:00
|
|
|
<li><p><code>alignof</code> (<a
|
|
|
|
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf">n2341</a>)</p></li>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p><code>constexpr</code> (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf">n2235</a>)
|
|
|
|
(<a
|
|
|
|
href="https://isocpp.org/files/papers/N3652.html">n3652</a>)</p></li>
|
|
|
|
<li><p>Sized deallocation (<a
|
|
|
|
href="https://isocpp.org/files/papers/n3778.html">n3778</a>)</p></li>
|
|
|
|
<li><p>Variadic templates (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf">n2242</a>)
|
|
|
|
(<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf">n2555</a>)</p></li>
|
|
|
|
<li><p>Static assertions (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html">n1720</a>)</p></li>
|
|
|
|
<li><p><code>decltype</code> (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf">n2343</a>)
|
|
|
|
(<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf">n3276</a>)</p></li>
|
|
|
|
<li><p>Right angle brackets (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html">n1757</a>)</p></li>
|
|
|
|
<li><p>Default template arguments for function templates (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226">CWG
|
|
|
|
D226</a>)</p></li>
|
|
|
|
<li><p>Template aliases (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf">n2258</a>)</p></li>
|
|
|
|
<li><p>Delegating constructors (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf">n1986</a>)</p></li>
|
|
|
|
<li><p>Explicit conversion operators (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf">n2437</a>)</p></li>
|
|
|
|
<li><p>Standard Layout Types (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm">n2342</a>)</p></li>
|
|
|
|
<li><p>Defaulted and deleted functions (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">n2346</a>)</p></li>
|
|
|
|
<li><p>Dynamic initialization and destruction with concurrency (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm">n2660</a>)</p></li>
|
|
|
|
<li><p><code>final</code> virtual specifiers for classes and virtual
|
|
|
|
functions (<a
|
|
|
|
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm">n2928</a>),
|
|
|
|
(<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm">n3206</a>),
|
|
|
|
(<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm">n3272</a>)</p></li>
|
|
|
|
<li><p><code>override</code> virtual specifiers for virtual functions
|
|
|
|
(<a
|
|
|
|
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm">n2928</a>),
|
|
|
|
(<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm">n3206</a>),
|
|
|
|
(<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm">n3272</a>)</p></li>
|
|
|
|
<li><p>Range-based <code>for</code> loops (<a
|
|
|
|
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html">n2930</a>)
|
|
|
|
(<a
|
|
|
|
href="https://en.cppreference.com/w/cpp/language/range-for">range-for</a>)</p></li>
|
|
|
|
<li><p>Unrestricted Unions (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf">n2544</a>)</p></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
|
|
|
<h3 id="excluded-features">Excluded Features</h3>
|
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p>New string and character literals</p>
|
2020-07-28 02:19:33 +00:00
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<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>
|
2020-07-28 02:19:33 +00:00
|
|
|
</ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>HotSpot doesn't need any of the new character and string literal
|
|
|
|
types.</p></li>
|
|
|
|
<li><p>User-defined literals (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf">n2765</a>)
|
|
|
|
— User-defined literals should not be added casually, but only through a
|
|
|
|
proposal to add a specific UDL.</p></li>
|
|
|
|
<li><p>Inline namespaces (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm">n2535</a>)
|
|
|
|
— HotSpot makes very limited use of namespaces.</p></li>
|
|
|
|
<li><p><code>using namespace</code> directives. In particular, don't use
|
|
|
|
<code>using namespace std;</code> to avoid needing to qualify Standard
|
|
|
|
Library names.</p></li>
|
|
|
|
<li><p>Propagating exceptions (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html">n2179</a>)
|
|
|
|
— HotSpot does not permit the use of exceptions, so this feature isn't
|
|
|
|
useful.</p></li>
|
|
|
|
<li><p>Avoid non-local variables with non-constexpr initialization. In
|
|
|
|
particular, avoid variables with types requiring non-trivial
|
|
|
|
initialization or destruction. Initialization order problems can be
|
|
|
|
difficult to deal with and lead to surprises, as can destruction
|
|
|
|
ordering. HotSpot doesn't generally try to cleanup on exit, and running
|
|
|
|
destructors at exit can also lead to problems.</p></li>
|
|
|
|
<li><p>Avoid most operator overloading, preferring named functions. When
|
|
|
|
operator overloading is used, ensure the semantics conform to the normal
|
|
|
|
expected behavior of the operation.</p></li>
|
|
|
|
<li><p>Avoid most implicit conversion constructors and (implicit or
|
|
|
|
explicit) conversion operators. (Note that conversion to
|
|
|
|
<code>bool</code> isn't needed in HotSpot code because of the "no
|
|
|
|
implicit boolean" guideline.)</p></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
<li><p>Avoid <code>goto</code> statements.</p></li>
|
|
|
|
</ul>
|
|
|
|
<h3 id="undecided-features">Undecided Features</h3>
|
2022-11-21 18:32:40 +00:00
|
|
|
<p>This list is incomplete; it serves to explicitly call out some
|
|
|
|
features that have not yet been discussed.</p>
|
2020-07-28 02:19:33 +00:00
|
|
|
<ul>
|
2022-11-21 18:32:40 +00:00
|
|
|
<li><p>Trailing return type syntax for functions (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm">n2541</a>)</p></li>
|
|
|
|
<li><p>Variable templates (<a
|
|
|
|
href="https://isocpp.org/files/papers/N3651.pdf">n3651</a>)</p></li>
|
|
|
|
<li><p>Member initializers and aggregates (<a
|
|
|
|
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html">n3653</a>)</p></li>
|
2020-07-28 02:19:33 +00:00
|
|
|
<li><p>Rvalue references and move semantics</p></li>
|
|
|
|
</ul>
|
|
|
|
</body>
|
|
|
|
</html>
|