1.. title:: clang-tidy - bugprone-easily-swappable-parameters 2 3bugprone-easily-swappable-parameters 4==================================== 5 6Finds function definitions where parameters of convertible types follow each 7other directly, making call sites prone to calling the function with 8swapped (or badly ordered) arguments. 9 10.. code-block:: c++ 11 12 void drawPoint(int X, int Y) { /* ... */ } 13 FILE *open(const char *Dir, const char *Name, Flags Mode) { /* ... */ } 14 15A potential call like ``drawPoint(-2, 5)`` or ``openPath("a.txt", "tmp", Read)`` 16is perfectly legal from the language's perspective, but might not be what the 17developer of the function intended. 18 19More elaborate and type-safe constructs, such as opaque typedefs or strong 20types should be used instead, to prevent a mistaken order of arguments. 21 22.. code-block:: c++ 23 24 struct Coord2D { int X; int Y; }; 25 void drawPoint(const Coord2D Pos) { /* ... */ } 26 27 FILE *open(const Path &Dir, const Filename &Name, Flags Mode) { /* ... */ } 28 29Due to the potentially elaborate refactoring and API-breaking that is necessary 30to strengthen the type safety of a project, no automatic fix-its are offered. 31 32Options 33------- 34 35Extension/relaxation options 36^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 37 38Relaxation (or extension) options can be used to broaden the scope of the 39analysis and fine-tune the enabling of more mixes between types. 40Some mixes may depend on coding style or preference specific to a project, 41however, it should be noted that enabling *all* of these relaxations model the 42way of mixing at call sites the most. 43These options are expected to make the check report for more functions, and 44report longer mixable ranges. 45 46.. option:: QualifiersMix 47 48 Whether to consider parameters of some *cvr-qualified* ``T`` and a 49 differently *cvr-qualified* ``T`` (i.e. ``T`` and ``const T``, ``const T`` 50 and ``volatile T``, etc.) mixable between one another. 51 If `false`, the check will consider differently qualified types unmixable. 52 `True` turns the warnings on. 53 Defaults to `false`. 54 55 The following example produces a diagnostic only if `QualifiersMix` is 56 enabled: 57 58 .. code-block:: c++ 59 60 void *memcpy(const void *Destination, void *Source, std::size_t N) { /* ... */ } 61 62.. option:: ModelImplicitConversions 63 64 Whether to consider parameters of type ``T`` and ``U`` mixable if there 65 exists an implicit conversion from ``T`` to ``U`` and ``U`` to ``T``. 66 If `false`, the check will not consider implicitly convertible types for 67 mixability. 68 `True` turns warnings for implicit conversions on. 69 Defaults to `true`. 70 71 The following examples produce a diagnostic only if 72 `ModelImplicitConversions` is enabled: 73 74 .. code-block:: c++ 75 76 void fun(int Int, double Double) { /* ... */ } 77 void compare(const char *CharBuf, std::string String) { /* ... */ } 78 79 .. note:: 80 81 Changing the qualifiers of an expression's type (e.g. from ``int`` to 82 ``const int``) is defined as an *implicit conversion* in the C++ 83 Standard. 84 However, the check separates this decision-making on the mixability of 85 differently qualified types based on whether `QualifiersMix` was 86 enabled. 87 88 For example, the following code snippet will only produce a diagnostic 89 if **both** `QualifiersMix` and `ModelImplicitConversions` are enabled: 90 91 .. code-block:: c++ 92 93 void fun2(int Int, const double Double) { /* ... */ } 94 95Filtering options 96^^^^^^^^^^^^^^^^^ 97 98Filtering options can be used to lessen the size of the diagnostics emitted by 99the checker, whether the aim is to ignore certain constructs or dampen the 100noisiness. 101 102.. option:: MinimumLength 103 104 The minimum length required from an adjacent parameter sequence to be 105 diagnosed. 106 Defaults to `2`. 107 Might be any positive integer greater or equal to `2`. 108 If `0` or `1` is given, the default value `2` will be used instead. 109 110 For example, if `3` is specified, the examples above will not be matched. 111 112.. option:: IgnoredParameterNames 113 114 The list of parameter **names** that should never be considered part of a 115 swappable adjacent parameter sequence. 116 The value is a `;`-separated list of names. 117 To ignore unnamed parameters, add `""` to the list verbatim (not the 118 empty string, but the two quotes, potentially escaped!). 119 **This option is case-sensitive!** 120 121 By default, the following parameter names, and their Uppercase-initial 122 variants are ignored: 123 `""` (unnamed parameters), `iterator`, `begin`, `end`, `first`, `last`, 124 `lhs`, `rhs`. 125 126.. option:: IgnoredParameterTypeSuffixes 127 128 The list of parameter **type name suffixes** that should never be 129 considered part of a swappable adjacent parameter sequence. 130 Parameters which type, as written in the source code, end with an element 131 of this option will be ignored. 132 The value is a `;`-separated list of names. 133 **This option is case-sensitive!** 134 135 By default, the following, and their lowercase-initial variants are ignored: 136 `bool`, `It`, `Iterator`, `InputIt`, `ForwardIt`, `BidirIt`, `RandomIt`, 137 `random_iterator`, `ReverseIt`, `reverse_iterator`, 138 `reverse_const_iterator`, `RandomIt`, `random_iterator`, `ReverseIt`, 139 `reverse_iterator`, `reverse_const_iterator`, `Const_Iterator`, 140 `ConstIterator`, `const_reverse_iterator`, `ConstReverseIterator`. 141 In addition, `_Bool` (but not `_bool`) is also part of the default value. 142 143.. option:: SuppressParametersUsedTogether 144 145 Suppresses diagnostics about parameters that are used together or in a 146 similar fashion inside the function's body. 147 Defaults to `true`. 148 Specifying `false` will turn off the heuristics. 149 150 Currently, the following heuristics are implemented which will suppress the 151 warning about the parameter pair involved: 152 153 * The parameters are used in the same expression, e.g. ``f(a, b)`` or 154 ``a < b``. 155 * The parameters are further passed to the same function to the same 156 parameter of that function, of the same overload. 157 E.g. ``f(a, 1)`` and ``f(b, 2)`` to some ``f(T, int)``. 158 159 .. note:: 160 161 The check does not perform path-sensitive analysis, and as such, 162 "same function" in this context means the same function declaration. 163 If the same member function of a type on two distinct instances are 164 called with the parameters, it will still be regarded as 165 "same function". 166 167 * The same member field is accessed, or member method is called of the 168 two parameters, e.g. ``a.foo()`` and ``b.foo()``. 169 * Separate ``return`` statements return either of the parameters on 170 different code paths. 171 172.. option:: NamePrefixSuffixSilenceDissimilarityTreshold 173 174 The number of characters two parameter names might be different on *either* 175 the head or the tail end with the rest of the name the same so that the 176 warning about the two parameters are silenced. 177 Defaults to `1`. 178 Might be any positive integer. 179 If `0`, the filtering heuristic based on the parameters' names is turned 180 off. 181 182 This option can be used to silence warnings about parameters where the 183 naming scheme indicates that the order of those parameters do not matter. 184 185 For example, the parameters ``LHS`` and ``RHS`` are 1-dissimilar suffixes 186 of each other: ``L`` and ``R`` is the different character, while ``HS`` 187 is the common suffix. 188 Similarly, parameters ``text1, text2, text3`` are 1-dissimilar prefixes 189 of each other, with the numbers at the end being the dissimilar part. 190 If the value is at least `1`, such cases will not be reported. 191 192 193Limitations 194----------- 195 196**This check is designed to check function signatures!** 197 198The check does not investigate functions that are generated by the compiler 199in a context that is only determined from a call site. 200These cases include variadic functions, functions in C code that do not have 201an argument list, and C++ template instantiations. 202Most of these cases, which are otherwise swappable from a caller's standpoint, 203have no way of getting "fixed" at the definition point. 204In the case of C++ templates, only primary template definitions and explicit 205specializations are matched and analyzed. 206 207None of the following cases produce a diagnostic: 208 209.. code-block:: c++ 210 211 int printf(const char *Format, ...) { /* ... */ } 212 int someOldCFunction() { /* ... */ } 213 214 template <typename T, typename U> 215 int add(T X, U Y) { return X + Y }; 216 217 void theseAreNotWarnedAbout() { 218 printf("%d %d\n", 1, 2); // Two ints passed, they could be swapped. 219 someOldCFunction(1, 2, 3); // Similarly, multiple ints passed. 220 221 add(1, 2); // Instantiates 'add<int, int>', but that's not a user-defined function. 222 } 223 224Due to the limitation above, parameters which type are further dependent upon 225template instantiations to *prove* that they mix with another parameter's is 226not diagnosed. 227 228.. code-block:: c++ 229 230 template <typename T> 231 struct Vector { 232 typedef T element_type; 233 }; 234 235 // Diagnosed: Explicit instantiation was done by the user, we can prove it 236 // is the same type. 237 void instantiated(int A, Vector<int>::element_type B) { /* ... */ } 238 239 // Diagnosed: The two parameter types are exactly the same. 240 template <typename T> 241 void exact(typename Vector<T>::element_type A, 242 typename Vector<T>::element_type B) { /* ... */ } 243 244 // Skipped: The two parameters are both 'T' but we cannot prove this 245 // without actually instantiating. 246 template <typename T> 247 void falseNegative(T A, typename Vector<T>::element_type B) { /* ... */ } 248 249In the context of *implicit conversions* (when `ModelImplicitConversions` is 250enabled), the modelling performed by the check 251warns if the parameters are swappable and the swapped order matches implicit 252conversions. 253It does not model whether there exists an unrelated third type from which 254*both* parameters can be given in a function call. 255This means that in the following example, even while ``strs()`` clearly carries 256the possibility to be called with swapped arguments (as long as the arguments 257are string literals), will not be warned about. 258 259.. code-block:: c++ 260 261 struct String { 262 String(const char *Buf); 263 }; 264 265 struct StringView { 266 StringView(const char *Buf); 267 operator const char *() const; 268 }; 269 270 // Skipped: Directly swapping expressions of the two type cannot mix. 271 // (Note: StringView -> const char * -> String would be **two** 272 // user-defined conversions, which is disallowed by the language.) 273 void strs(String Str, StringView SV) { /* ... */ } 274 275 // Diagnosed: StringView implicitly converts to and from a buffer. 276 void cStr(StringView SV, const char *Buf() { /* ... */ } 277