Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Scott Snyder
coding-rules
Commits
abb62a6e
Commit
abb62a6e
authored
Sep 17, 2019
by
scott snyder
Browse files
Minor cleanups and updates to take into acount that we now require C++17.
parent
d17c9f5e
Changes
1
Hide whitespace changes
Inline
Side-by-side
rules.org
View file @
abb62a6e
#+
MACRO
:
version
0.7
#+
LaTeX_HEADER
:
\
def
\
rulesversion
{
0.7
}
#+
TITLE
:
ATLAS
C
++
coding
guidelines
,
version
{{{
version
}}}
#+
AUTHOR
:
S
haun
Roe
(
CERN
),
Scott
Snyder
(
BNL
),
and
the
former
ATLAS
Quality
Control
group
#+
AUTHOR
:
S
cott
Snyder
(
BNL
),
Shaun
Roe
(
CERN
),
and
the
former
ATLAS
Quality
Control
group
#+
EMAIL
:
Correspondence
to
snyder
@
bnl
.
gov
.
#
Checked
with
org
-
mode
9.1.9
(
as
bundled
with
emacs
26.2
)
#
To
export
to
PDF
use
`
org
-
latex
-
export
-
to
-
pdf
'.
...
...
@@ -63,7 +63,7 @@ This document is derived from the original ATLAS C++ coding standard,
derived
from
work
done
by
the
CERN
``
Project
support
team
''
and
SPIDER
project
,
as
documented
in
[[
http
://
pst
.
web
.
cern
.
ch
/
PST
/
HandBookWorkBook
/
Handbook
/
Programming
/
CodingStandard
/
c
++
standard
.
pdf
][
CERN
-
UCO
/
1999
/
207
]]
[
fn
:
PST99
].
These
previous
guidelines
have
been
significantly
revised
to
take
into
account
the
evolution
of
the
C
++
language
[
fn
:
Cxx1
4
],
to
take
into
account
the
evolution
of
the
C
++
language
[
fn
:
Cxx1
7
],
current
practices
in
ATLAS
,
and
the
experience
gained
over
the
past
decade
.
...
...
@@ -440,8 +440,8 @@ vector<int> x; // Missing std!
Otherwise
,
the
=
using
=
may
serve
to
hide
problems
with
missing
namespace
qualifications
in
the
headers
.
Starting
with
C
++
11
,
=
using
=
can
also
be
used
in
ways
similar
to
=
typedef
=.
Such
usage
is
not
covered
by
this
rule
.
This
rule
does
not
apply
when
=
using
=
is
used
to
define
a
new
name
for
a
type
(
similarly
to
=
typedef
=)
.
**
Control
flow
...
...
@@ -455,8 +455,8 @@ vector<int> x; // Missing std!
-
*
Prefer
range
-
based
for
loops
.*
[<<
prefer
-
range
-
based
-
for
>>]
C
++
11
introduced
the
`
range
-
based
for
'. Prefer using this
to a loop
with explicit iterators
; t
hat is, prefer:
Prefer
a
range
-
based
for
to
a
loop
with
explicit
iterators
.
T
hat
is
,
prefer
:
#+
BEGIN_EXAMPLE
std
::
vector
<
int
>
v
=
...;
for
(
int
x
:
v
)
{
...
...
@@ -499,22 +499,23 @@ for (std::vector<int>::const_iterator it = v.begin();
If you must ``fall through'' from one switch clause to another
(excluding the trivial case of a clause with no statements),
this
must
be
explicitly
stated
in
a
comment
.
This
should
,
however
,
be
a
rare
case
.
this
should
be explicitly
indicated using the =fallthough= attribute.
This should,
however, be a rare case.
#+BEGIN_EXAMPLE
switch (case) {
case 1:
doSomething();
/*
FALLTHROUGH
*/
[[fallthrough]];
case 2:
doSomethingMore();
break;
...
#+END_EXAMPLE
gcc7
will
warn
about
such
constructs
unless
you
use
a
comment
like
in
the
example
above
.
(
C
++
17
will
add
a
=
fallthrough
=
attribute
.)
Recent compilers will warn about such constructs unless you use
the attribute or a special comment. For new code, using the
attribute is preferred.
- *An if-statement which does not fit in one line must have braces
...
...
@@ -674,7 +675,7 @@ int* ip, jp;
- *Be conservative in using* =auto=. [<<using-auto>>]
C
++
11
includes
the
new
=
auto
=
keyword
,
which
allows
one
to
omit
explicitly
The
=auto= keyword allows one to omit explicitly
writing types that the compile can deduce. Examples:
#+BEGIN_EXAMPLE
...
...
@@ -706,6 +707,28 @@ auto foo = doSomething();
foo->doSomethingElse();
#+END_EXAMPLE
=auto= has also been observed to be a frequent source of errors
leading to unwanted copies of objects. For example, in this code:
#+BEGIN_EXAMPLE
std::vector<std::vector<int> > arr = ...;
for (auto v : arr) {
for (auto elt : v) { ...
#+END_EXAMPLE
each element of the outermost vector will be copied, as the assignment
to =v= will be done by value. One would probably want:
#+BEGIN_EXAMPLE
std::vector<std::vector<int> > arr = ...;
for (const auto& v : arr) {
for (auto elt : v) { ...
#+END_EXAMPLE
but having to be aware of the type like this kind of obviates the
motivation for using =auto= in the first place. Using the type
explicitly makes this sort of error much more difficult.
The current recommendation is to generally not use =auto= in place of a
(possibly-qualified) simple type:
...
...
@@ -925,8 +948,9 @@ public:
};
#+
END_EXAMPLE
This syntax was new in C++11. In C++98
, this was achieved
In
older
versions
of
the
language
,
this
was
achieved
by
declaring
the
deleted
methods
as
private
(
and
not
implementing
them
).
For
new
code
,
prefer
explicitly
deleting
the
functions
.
#+
BEGIN_EXAMPLE
//
There
is
only
one
ATLASExperimentalHall
,
...
...
@@ -1257,7 +1281,7 @@ void foo (std::unique_ptr<Object> obj);
Here are a some additional examples to illustrate this.
Assume that class =C= contains a member =Foo* m_owning_pointer=
which
the
class
deletes
.
(
In
C
++
11
,
it
would
of
course
usually
be
better
for
which the class deletes. (In
modern
C++, it would of course usually be better for
this to be a =unique_ptr=.)
#+BEGIN_EXAMPLE
// --- Best
...
...
@@ -1327,7 +1351,8 @@ std::unique_ptr<Foo> makeFoo()
}
// Ok if documented
//
makeFoo
()
returns
a
newly
-
allocated
Foo
;
caller
must
delete
it
.
// makeFoo() returns a newly-allocated Foo;
// caller must delete it.
Foo* makeFoo()
{
return new Foo (...);
...
...
@@ -1499,7 +1524,7 @@ void foo (std::unique_ptr<C> ptr);
...
std::unique_ptr<C> p (new C);
...
foo
(
p
);
foo (
std::move (p)
);
// The argument of foo() is initialized by move.
// p is left as a null pointer.
#+END_EXAMPLE
...
...
@@ -1985,6 +2010,7 @@ private:
=MsgStream=. No production code should use =cout=. Classes which are not
Athena-aware could use =cerr= before throwing an exception, but all
Athena-aware classes should use =MSG::FATAL= and/or throw an exception.
In addition, it is acceptible to use writes to =cout= in unit tests.
When using =MsgStream=, note that a call to, e.g.,
~msg() << MSG::VERBOSE~ that is suppressed by the output level has a higher
...
...
@@ -1994,7 +2020,6 @@ private:
statements and are preferred in general for two reasons: they take
up less space in the source code and indicate immediately that the
message is correctly handled.
- *Check for all errors reported from functions.* [<<check-return-status>>]
...
...
@@ -2064,12 +2089,11 @@ public:
to
check
,
at
runtime
,
that
a
function
did
not
throw
any
but
a
restricted
set
of
exceptions
.
Experience has shown that exception specifications are generally not useful,
and they have been deprecated in C++11 [fn:Sutter02]. They should not
be used in new code. In C++17, the use of non-empty exception specifications
is an error.
Experience
has
shown
that
exception
specifications
are
generally
not
useful
and
non
-
empty
exception
specifications
are
now
an
error
[
fn
:
Sutter02
].
They
should
not
be
used
in
new
code
.
C++14 added a new =noexcept= keyword. However, t
he motivation for this was
There
is
also
the
keyword
=
noexcept
=.
T
he
motivation
for
this
was
really
to
address
a
specific
problem
with
move
constructors
and
exception
-
safety
,
and
it
is
not
clear
that
it
is
generally
useful
[
fn
:
Krzemienski14
].
...
...
@@ -2161,6 +2185,7 @@ Exception: std::exception
Exception: Mine!
#+END_EXAMPLE
Recent versions of gcc will warn about this.
** Parts of C++ to avoid
...
...
@@ -2258,7 +2283,7 @@ void error(int severity, ...) // "severity" followed by a
// NOT recommended to have function-like macro
#define SQUARE(x) x*x
Better to define an inline function:
//
Better to define an inline function:
inline int square(int x) {
return x*x;
};
...
...
@@ -2422,14 +2447,7 @@ some machines, left-to-right on others. -- end note ]
have
long
been
able
to
do
a
good
job
of
assigning
values
to
registers
;
this
is
anyway
highly
-
machine
dependent
.
The
=
register
=
keyword
is
ignored
by
all
modern
compilers
,
and
has
been
deprecated
in
the
C
++
standard
for
some
time
.
As
of
C
++
17
,
using
the
=
register
=
keyword
is
an
error
.
If
you
absolutely
need
to
assign
a
variable
to
a
register
,
many
compilers
have
a
way
of
doing
this
using
inline
assembly
or
a
related
facility
.
This
is
,
however
,
inherently
compiler
-
and
machine
-
dependent
,
and
would
only
be
useful
in
very
special
cases
.
Use
of
the
=
register
=
keyword
now
an
error
.
**
Readability
and
maintainability
...
...
@@ -2547,12 +2565,12 @@ float ip_cut = 0.1 * Gaudi::Units::cm;
** Portability
- *All code must comply with the 201
4
version of the ISO C++ standard (C++1
4
)*. [<<standard-cxx>>]
- *All code must comply with the 201
7
version of the ISO C++ standard (C++1
7
)*. [<<standard-cxx>>]
A draft of the standard which is essentially identical to the final version
may be found at [fn:Cxx1
4
].
may be found at [fn:Cxx1
7
].
At some point, compatibility with C++
17
will also be required.
At some point, compatibility with C++
20
will also be required.
- *Make non-portable code easy to find and replace.* [<<limit-non-portable-code>>]
...
...
@@ -2587,8 +2605,8 @@ float ip_cut = 0.1 * Gaudi::Units::cm;
fail elsewhere.
The ATLAS convention is to include the package name followed by the file name.
Watch out:
if you
list the package name twice
, compilation will work
with CMT, but it may not work with other build systems
.
Watch out: list the package name twice
is wrong, but some build systems
don'
t
catch
it
.
#+
BEGIN_EXAMPLE
#
include
"/afs/cern.ch/atlas/software/dist/1.2.1/Foo/Bar/Qux.h"
...
...
@@ -2987,7 +3005,9 @@ The comment includes the fact that it is the perpendicular distance.
*
Changes
**
Version
0.7
- Allow omitting the =default= clause in a =swtich= statement on an =enum=
-
Minor
cleanups
and
updates
to
take
into
acount
that
we
now
require
C
++
17.
-
Use
the
=
fallthough
=
attribute
,
not
a
comment
.
-
Allow
omitting
the
=
default
=
clause
in
a
=
switch
=
statement
on
an
=
enum
=
that
handles
all
possible
values
.
Recent
compilers
will
warn
if
some
values
are
not
handled
,
and
it
's better to get such a diagnosic
at compile-time rather than at runtime.
...
...
@@ -3034,7 +3054,7 @@ The comment includes the fact that it is the perpendicular distance.
[fn:GOF] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, /Design Patterns, Elements of Reusable Object-Oriented Software/, Addison-Wesley.
[fn:Sutter02] [[http://www.gotw.ca/publications/mill22.htm][H. Sutter, /C++ Users Journal/, *20* (7), 2002.]]
[fn:Krzemienski14] [[http://akrzemi1.wordpress.com/2014/04/24/noexcept-what-for/][A. Krzemie\nacute{}ski, /noexcept --- what for?/, 2014.]]
[
fn
:
Cxx1
4
]
[[
https
://
github
.
com
/
cplusplus
/
draft
/
blob
/
master
/
papers
/
n4
140
.
pdf
][
/
Standard
for
the
Programming
Language
C
++/,
n4
140
.]]
[fn:Cxx1
7
] [[https://github.com/cplusplus/draft/blob/master/papers/n4
659
.pdf][ /Standard for the Programming Language C++/, n4
659
.]]
[fn:Warnings] [[https://twiki.cern.ch/twiki/bin/view/AtlasComputing/FaqCompileTimeWarnings][FaqCompileTimeWarnings ATLAS wiki page.]]
[fn:Doxygen] [[https://twiki.cern.ch/twiki/bin/view/AtlasComputing/DoxygenDocumentation][DoxygenDocumentation ATLAS wiki page.]]
...
...
@@ -3148,5 +3168,5 @@ Doxygen also knows about //!< , I think?
# eval: (defun org-html-target (target contents info) (let ((id (org-export-solidify-link-text (org-element-property :value target)))) (org-html--anchor id id)))
# eval: (setq org-export-with-email t)
# eval: (setq org-latex-prefer-user-labels t)
# eval: (define-advice org-latex--text-markup (:filter-return (text) brocket-fix)
(if (string= (substring text 0 8) "
\\
texttt
{
")
(replace-regexp-in-string "
<<
" "
<{}<
" text) text)) ; fix bad formatting of <<
# eval: (define-advice org-latex--text-markup (:filter-return (text) brocket-fix) (if (string= (substring text 0 8) "\\texttt{") (replace-regexp-in-string "<<" "<{}<"
(replace-regexp-in-string ">>" ">{}>"
text)
)
text)) ; fix bad formatting of <<
and >>
# End:
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment