Commit fae08d49 authored by scott snyder's avatar scott snyder
Browse files

Add note on use of auto.

parent 3f8b838f
#+MACRO: version 0.1
#+TITLE: Using auto in ATLAS code
#+AUTHOR: Scott Snyder
# Put a frame around examples in LaTeX.
#+LaTeX_HEADER: \usepackage{fancyvrb}
#+LaTeX_HEADER: \RecustomVerbatimEnvironment{verbatim}{Verbatim}{frame=single}
#+LaTeX_HEADER: \usepackage{lineno}
#+LaTeX_HEADER: \linenumbers
#+LaTeX_HEADER: \usepackage{fancyhdr}
#+LaTeX_HEADER: \pagestyle{fancy}
#+LaTeX_HEADER: \rfoot{Version {{{version}}}}
#+LaTeX_HEADER: \lhead{}
This short note is on the proper use of the =auto= keyword
in ATLAS code.
C++11 includes the new =auto= keyword, which allows one to omit explicitly
writing types that the compile can deduce. Examples:
#+BEGIN_EXAMPLE
auto x = 10; // Type int deduced
auto y = 42ul; // Type unsigned long deduced.
auto it = vec.begin(); // Iterator type deduced
#+END_EXAMPLE
Some authorities have recommended using =auto= pretty much everywhere
you can (calling it ``auto almost always''). However, our experience
has been that this adversely affects the readability and robustness
of the code. It generally helps a reader to understand what the code
is doing if the type is apparent, but with =auto=, it often isn't.
Using =auto= also makes it more difficult to find places where
a particular type is used when searching the code with tools
like lxr. It can also make it more difficult to track errors back
to their source:
#+BEGIN_EXAMPLE
const Foo* doSomething();
... a lot of code here ...
auto foo = doSomething();
// What is the type of foo here? You have to look up
// doSomething() in order to find out! Makes it much
// harder to find all places where the type Foo gets used.
// If the return type of doSomething() changes, you'll get
// an error here, not at the doSomething() call.
foo->doSomethingElse();
#+END_EXAMPLE
The current recommendation is to generally not use =auto= in place of a
(possibly-qualified) simple type:
#+BEGIN_EXAMPLE
// Use these
int x = 42;
const Foo* foo = doSomething();
for (const CaloCell* cell : caloCellContainer) ...
Foo foo (x);
// Rather than these
auto x = 42;
auto foo = doSomething();
for (auto cell : caloCellContainer) ...
auto foo = Foo {x};
#+END_EXAMPLE
There are three sorts of places where it generally makes sense to
use =auto=.
- When the type is already evident in the expression and the declaration
would be redundant. This is usually the case for expressions
with =new= or =make_unique=.
#+BEGIN_EXAMPLE
// auto is fine here.
auto foo = new Foo;
auto ufoo = std::make_unique<Foo>();
#+END_EXAMPLE
- When you need a declaration for a complicated derived type, where
the type itself isn't of much interest.
#+BEGIN_EXAMPLE
// Fine to use auto here; the full name of the type
// is too cumbersome to be useful.
std::map<int, std::string> m = ..;
auto ret = m.insert (std::make_pair (1, "x"));
if (ret.second) ....
#+END_EXAMPLE
- =auto= may also be useful in writing generic template code.
In general, the decision as to whether or not to use =auto= should
be made on the basis of what makes the code easier to _read_.
It is bad practice to use it simply to save a few characters
of typing.
# Local Variables:
# eval: (setq org-export-with-toc nil)
# End:
# LocalWords: LaTeX usepackage fancyvrb RecustomVerbatimEnvironment
# LocalWords: lineno linenumbers fancyhdr pagestyle rfoot lhead vec
# LocalWords: 42ul lxr const doSomething doSomethingElse CaloCell
# LocalWords: caloCellContainer ufoo ret eval setq toc
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment