.. title:: clang-tidy - modernize-use-auto

modernize-use-auto
==================

This check is responsible for using the ``auto`` type specifier for variable
declarations to *improve code readability and maintainability*. For example:

.. code-block:: c++

  std::vector<int>::iterator I = my_container.begin();

  // transforms to:

  auto I = my_container.begin();

The ``auto`` type specifier will only be introduced in situations where the
variable type matches the type of the initializer expression. In other words
``auto`` should deduce the same type that was originally spelled in the source.
However, not every situation should be transformed:

.. code-block:: c++

  int val = 42;
  InfoStruct &I = SomeObject.getInfo();

  // Should not become:

  auto val = 42;
  auto &I = SomeObject.getInfo();

In this example using ``auto`` for builtins doesn't improve readability. In
other situations it makes the code less self-documenting impairing readability
and maintainability. As a result, ``auto`` is used only introduced in specific
situations described below.

Iterators
---------

Iterator type specifiers tend to be long and used frequently, especially in
loop constructs. Since the functions generating iterators have a common format,
the type specifier can be replaced without obscuring the meaning of code while
improving readability and maintainability.

.. code-block:: c++

  for (std::vector<int>::iterator I = my_container.begin(),
                                  E = my_container.end();
       I != E; ++I) {
  }

  // becomes

  for (auto I = my_container.begin(), E = my_container.end(); I != E; ++I) {
  }

The check will only replace iterator type-specifiers when all of the following
conditions are satisfied:

* The iterator is for one of the standard containers in ``std`` namespace:

  * ``array``
  * ``deque``
  * ``forward_list``
  * ``list``
  * ``vector``
  * ``map``
  * ``multimap``
  * ``set``
  * ``multiset``
  * ``unordered_map``
  * ``unordered_multimap``
  * ``unordered_set``
  * ``unordered_multiset``
  * ``queue``
  * ``priority_queue``
  * ``stack``

* The iterator is one of the possible iterator types for standard containers:

  * ``iterator``
  * ``reverse_iterator``
  * ``const_iterator``
  * ``const_reverse_iterator``

* In addition to using iterator types directly, typedefs or other ways of
  referring to those types are also allowed. However, implementation-specific
  types for which a type like ``std::vector<int>::iterator`` is itself a
  typedef will not be transformed. Consider the following examples:

.. code-block:: c++

  // The following direct uses of iterator types will be transformed.
  std::vector<int>::iterator I = MyVec.begin();
  {
    using namespace std;
    list<int>::iterator I = MyList.begin();
  }

  // The type specifier for J would transform to auto since it's a typedef
  // to a standard iterator type.
  typedef std::map<int, std::string>::const_iterator map_iterator;
  map_iterator J = MyMap.begin();

  // The following implementation-specific iterator type for which
  // std::vector<int>::iterator could be a typedef would not be transformed.
  __gnu_cxx::__normal_iterator<int*, std::vector> K = MyVec.begin();

* The initializer for the variable being declared is not a braced initializer
  list. Otherwise, use of ``auto`` would cause the type of the variable to be
  deduced as ``std::initializer_list``.

New expressions
---------------

Frequently, when a pointer is declared and initialized with ``new``, the
pointee type is written twice: in the declaration type and in the
``new`` expression. In this case, the declaration type can be replaced with
``auto`` improving readability and maintainability.

.. code-block:: c++

  TypeName *my_pointer = new TypeName(my_param);

  // becomes

  auto *my_pointer = new TypeName(my_param);

The check will also replace the declaration type in multiple declarations, if
the following conditions are satisfied:

* All declared variables have the same type (i.e. all of them are pointers to
  the same type).
* All declared variables are initialized with a ``new`` expression.
* The types of all the new expressions are the same than the pointee of the
  declaration type.

.. code-block:: c++

  TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;

  // becomes

  auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;

Cast expressions
----------------

Frequently, when a variable is declared and initialized with a cast, the
variable type is written twice: in the declaration type and in the
cast expression. In this case, the declaration type can be replaced with
``auto`` improving readability and maintainability.

.. code-block:: c++

  TypeName *my_pointer = static_cast<TypeName>(my_param);

  // becomes

  auto *my_pointer = static_cast<TypeName>(my_param);

The check handles ``static_cast``, ``dynamic_cast``, ``const_cast``,
``reinterpret_cast``, functional casts, C-style casts and function templates
that behave as casts, such as ``llvm::dyn_cast``, ``boost::lexical_cast`` and
``gsl::narrow_cast``. Calls to function templates are considered to behave as
casts if the first template argument is explicit and is a type, and the function
returns that type, or a pointer or reference to it.

Known Limitations
-----------------

* If the initializer is an explicit conversion constructor, the check will not
  replace the type specifier even though it would be safe to do so.

* User-defined iterators are not handled at this time.

Options
-------

.. option:: MinTypeNameLength

   If the option is set to non-zero (default `5`), the check will ignore type
   names having a length less than the option value. The option affects
   expressions only, not iterators.
   Spaces between multi-lexeme type names (``long int``) are considered as one.
   If the :option:`RemoveStars` option (see below) is set to `true`, then ``*s``
   in the type are also counted as a part of the type name.

.. code-block:: c++

  // MinTypeNameLength = 0, RemoveStars=0

  int a = static_cast<int>(foo());            // ---> auto a = ...
  // length(bool *) = 4
  bool *b = new bool;                         // ---> auto *b = ...
  unsigned c = static_cast<unsigned>(foo());  // ---> auto c = ...

  // MinTypeNameLength = 5, RemoveStars=0

  int a = static_cast<int>(foo());                 // ---> int  a = ...
  bool b = static_cast<bool>(foo());               // ---> bool b = ...
  bool *pb = static_cast<bool*>(foo());            // ---> bool *pb = ...
  unsigned c = static_cast<unsigned>(foo());       // ---> auto c = ...
  // length(long <on-or-more-spaces> int) = 8
  long int d = static_cast<long int>(foo());       // ---> auto d = ...

  // MinTypeNameLength = 5, RemoveStars=1

  int a = static_cast<int>(foo());                 // ---> int  a = ...
  // length(int * * ) = 5
  int **pa = static_cast<int**>(foo());            // ---> auto pa = ...
  bool b = static_cast<bool>(foo());               // ---> bool b = ...
  bool *pb = static_cast<bool*>(foo());            // ---> auto pb = ...
  unsigned c = static_cast<unsigned>(foo());       // ---> auto c = ...
  long int d = static_cast<long int>(foo());       // ---> auto d = ...

.. option:: RemoveStars

   If the option is set to `true` (default is `false`), the check will remove
   stars from the non-typedef pointer types when replacing type names with
   ``auto``. Otherwise, the check will leave stars. For example:

.. code-block:: c++

  TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;

  // RemoveStars = 0

  auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;

  // RemoveStars = 1

  auto my_first_pointer = new TypeName, my_second_pointer = new TypeName;
