brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 3cd37e0 Raw
235 lines · plain
1.. title:: clang-tidy - modernize-use-auto2 3modernize-use-auto4==================5 6This check is responsible for using the ``auto`` type specifier for variable7declarations to *improve code readability and maintainability*. For example:8 9.. code-block:: c++10 11  std::vector<int>::iterator I = my_container.begin();12 13  // transforms to:14 15  auto I = my_container.begin();16 17The ``auto`` type specifier will only be introduced in situations where the18variable type matches the type of the initializer expression. In other words19``auto`` should deduce the same type that was originally spelled in the source.20However, not every situation should be transformed:21 22.. code-block:: c++23 24  int val = 42;25  InfoStruct &I = SomeObject.getInfo();26 27  // Should not become:28 29  auto val = 42;30  auto &I = SomeObject.getInfo();31 32In this example using ``auto`` for builtins doesn't improve readability. In33other situations it makes the code less self-documenting impairing readability34and maintainability. As a result, ``auto`` is used only introduced in specific35situations described below.36 37Iterators38---------39 40Iterator type specifiers tend to be long and used frequently, especially in41loop constructs. Since the functions generating iterators have a common format,42the type specifier can be replaced without obscuring the meaning of code while43improving readability and maintainability.44 45.. code-block:: c++46 47  for (std::vector<int>::iterator I = my_container.begin(),48                                  E = my_container.end();49       I != E; ++I) {50  }51 52  // becomes53 54  for (auto I = my_container.begin(), E = my_container.end(); I != E; ++I) {55  }56 57The check will only replace iterator type-specifiers when all of the following58conditions are satisfied:59 60* The iterator is for one of the standard containers in ``std`` namespace:61 62  * ``array``63  * ``deque``64  * ``forward_list``65  * ``list``66  * ``vector``67  * ``map``68  * ``multimap``69  * ``set``70  * ``multiset``71  * ``unordered_map``72  * ``unordered_multimap``73  * ``unordered_set``74  * ``unordered_multiset``75  * ``queue``76  * ``priority_queue``77  * ``stack``78 79* The iterator is one of the possible iterator types for standard containers:80 81  * ``iterator``82  * ``reverse_iterator``83  * ``const_iterator``84  * ``const_reverse_iterator``85 86* In addition to using iterator types directly, typedefs or other ways of87  referring to those types are also allowed. However, implementation-specific88  types for which a type like ``std::vector<int>::iterator`` is itself a89  typedef will not be transformed. Consider the following examples:90 91.. code-block:: c++92 93  // The following direct uses of iterator types will be transformed.94  std::vector<int>::iterator I = MyVec.begin();95  {96    using namespace std;97    list<int>::iterator I = MyList.begin();98  }99 100  // The type specifier for J would transform to auto since it's a typedef101  // to a standard iterator type.102  typedef std::map<int, std::string>::const_iterator map_iterator;103  map_iterator J = MyMap.begin();104 105  // The following implementation-specific iterator type for which106  // std::vector<int>::iterator could be a typedef would not be transformed.107  __gnu_cxx::__normal_iterator<int*, std::vector> K = MyVec.begin();108 109* The initializer for the variable being declared is not a braced initializer110  list. Otherwise, use of ``auto`` would cause the type of the variable to be111  deduced as ``std::initializer_list``.112 113New expressions114---------------115 116Frequently, when a pointer is declared and initialized with ``new``, the117pointee type is written twice: in the declaration type and in the118``new`` expression. In this case, the declaration type can be replaced with119``auto`` improving readability and maintainability.120 121.. code-block:: c++122 123  TypeName *my_pointer = new TypeName(my_param);124 125  // becomes126 127  auto *my_pointer = new TypeName(my_param);128 129The check will also replace the declaration type in multiple declarations, if130the following conditions are satisfied:131 132* All declared variables have the same type (i.e. all of them are pointers to133  the same type).134* All declared variables are initialized with a ``new`` expression.135* The types of all the new expressions are the same than the pointee of the136  declaration type.137 138.. code-block:: c++139 140  TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;141 142  // becomes143 144  auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;145 146Cast expressions147----------------148 149Frequently, when a variable is declared and initialized with a cast, the150variable type is written twice: in the declaration type and in the151cast expression. In this case, the declaration type can be replaced with152``auto`` improving readability and maintainability.153 154.. code-block:: c++155 156  TypeName *my_pointer = static_cast<TypeName>(my_param);157 158  // becomes159 160  auto *my_pointer = static_cast<TypeName>(my_param);161 162The check handles ``static_cast``, ``dynamic_cast``, ``const_cast``,163``reinterpret_cast``, functional casts, C-style casts and function templates164that behave as casts, such as ``llvm::dyn_cast``, ``boost::lexical_cast`` and165``gsl::narrow_cast``. Calls to function templates are considered to behave as166casts if the first template argument is explicit and is a type, and the167function returns that type, or a pointer or reference to it.168 169 170Limitations171-----------172 173* If the initializer is an explicit conversion constructor, the check will not174  replace the type specifier even though it would be safe to do so.175 176* User-defined iterators are not handled at this time.177 178Options179-------180 181.. option:: MinTypeNameLength182 183   If the option is set to non-zero (default `5`), the check will ignore type184   names having a length less than the option value. The option affects185   expressions only, not iterators.186   Spaces between multi-lexeme type names (``long int``) are considered as one.187   If the :option:`RemoveStars` option (see below) is set to `true`, then ``*s``188   in the type are also counted as a part of the type name.189 190.. code-block:: c++191 192  // MinTypeNameLength = 0, RemoveStars=0193 194  int a = static_cast<int>(foo());            // ---> auto a = ...195  // length(bool *) = 4196  bool *b = new bool;                         // ---> auto *b = ...197  unsigned c = static_cast<unsigned>(foo());  // ---> auto c = ...198 199  // MinTypeNameLength = 5, RemoveStars=0200 201  int a = static_cast<int>(foo());                 // ---> int  a = ...202  bool b = static_cast<bool>(foo());               // ---> bool b = ...203  bool *pb = static_cast<bool*>(foo());            // ---> bool *pb = ...204  unsigned c = static_cast<unsigned>(foo());       // ---> auto c = ...205  // length(long <on-or-more-spaces> int) = 8206  long int d = static_cast<long int>(foo());       // ---> auto d = ...207 208  // MinTypeNameLength = 5, RemoveStars=1209 210  int a = static_cast<int>(foo());                 // ---> int  a = ...211  // length(int * * ) = 5212  int **pa = static_cast<int**>(foo());            // ---> auto pa = ...213  bool b = static_cast<bool>(foo());               // ---> bool b = ...214  bool *pb = static_cast<bool*>(foo());            // ---> auto pb = ...215  unsigned c = static_cast<unsigned>(foo());       // ---> auto c = ...216  long int d = static_cast<long int>(foo());       // ---> auto d = ...217 218.. option:: RemoveStars219 220   If the option is set to `true` (default is `false`), the check will remove221   stars from the non-typedef pointer types when replacing type names with222   ``auto``. Otherwise, the check will leave stars. For example:223 224.. code-block:: c++225 226  TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;227 228  // RemoveStars = 0229 230  auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;231 232  // RemoveStars = 1233 234  auto my_first_pointer = new TypeName, my_second_pointer = new TypeName;235