1.. title:: clang-tidy - cppcoreguidelines-narrowing-conversions
2
3cppcoreguidelines-narrowing-conversions
4=======================================
5
6Checks for silent narrowing conversions, e.g: ``int i = 0; i += 0.1;``. While
7the issue is obvious in this former example, it might not be so in the
8following: ``void MyClass::f(double d) { int_member_ += d; }``.
9
10This rule is part of the "Expressions and statements" profile of the C++ Core
11Guidelines, corresponding to rule ES.46. See
12
13https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es46-avoid-lossy-narrowing-truncating-arithmetic-conversions.
14
15We enforce only part of the guideline, more specifically, we flag narrowing conversions from:
16 - an integer to a narrower integer (e.g. ``char`` to ``unsigned char``)
17   if WarnOnIntegerNarrowingConversion Option is set,
18 - an integer to a narrower floating-point (e.g. ``uint64_t`` to ``float``),
19 - a floating-point to an integer (e.g. ``double`` to ``int``),
20 - a floating-point to a narrower floating-point (e.g. ``double`` to ``float``)
21   if WarnOnFloatingPointNarrowingConversion Option is set.
22
23This check will flag:
24 - All narrowing conversions that are not marked by an explicit cast (c-style or
25   ``static_cast``). For example: ``int i = 0; i += 0.1;``,
26   ``void f(int); f(0.1);``,
27 - All applications of binary operators with a narrowing conversions.
28   For example: ``int i; i+= 0.1;``.
29
30
31Options
32-------
33
34.. option:: WarnOnIntegerNarrowingConversion
35
36    When `true`, the check will warn on narrowing integer conversion
37    (e.g. ``int`` to ``size_t``). `true` by default.
38
39.. option:: WarnOnFloatingPointNarrowingConversion
40
41    When `true`, the check will warn on narrowing floating point conversion
42    (e.g. ``double`` to ``float``). `true` by default.
43
44.. option:: WarnWithinTemplateInstantiation
45
46    When `true`, the check will warn on narrowing conversions within template
47    instantations. `false` by default.
48
49.. option:: WarnOnEquivalentBitWidth
50
51    When `true`, the check will warn on narrowing conversions that arise from
52    casting between types of equivalent bit width. (e.g.
53    `int n = uint(0);` or `long long n = double(0);`) `true` by default.
54
55.. option:: IgnoreConversionFromTypes
56
57   Narrowing conversions from any type in this semicolon-separated list will be
58   ignored. This may be useful to weed out commonly occurring, but less commonly
59   problematic assignments such as `int n = std::vector<char>().size();` or
60   `int n = std::difference(it1, it2);`. The default list is empty, but one
61   suggested list for a legacy codebase would be
62   `size_t;ptrdiff_t;size_type;difference_type`.
63
64.. option:: PedanticMode
65
66    When `true`, the check will warn on assigning a floating point constant
67    to an integer value even if the floating point value is exactly
68    representable in the destination type (e.g. ``int i = 1.0;``).
69    `false` by default.
70
71FAQ
72---
73
74 - What does "narrowing conversion from 'int' to 'float'" mean?
75
76An IEEE754 Floating Point number can represent all integer values in the range
77[-2^PrecisionBits, 2^PrecisionBits] where PrecisionBits is the number of bits in
78the mantissa.
79
80For ``float`` this would be [-2^23, 2^23], where ``int`` can represent values in
81the range [-2^31, 2^31-1].
82
83 - What does "implementation-defined" mean?
84
85You may have encountered messages like "narrowing conversion from 'unsigned int'
86to signed type 'int' is implementation-defined".
87The C/C++ standard does not mandate two’s complement for signed integers, and so
88the compiler is free to define what the semantics are for converting an unsigned
89integer to signed integer. Clang's implementation uses the two’s complement
90format.
91