1 .. title:: clang-tidy - bugprone-narrowing-conversions
3 bugprone-narrowing-conversions
4 ==============================
6 `cppcoreguidelines-narrowing-conversions` redirects here as an alias for this check.
8 Checks for silent narrowing conversions, e.g: ``int i = 0; i += 0.1;``. While
9 the issue is obvious in this former example, it might not be so in the
10 following: ``void MyClass::f(double d) { int_member_ += d; }``.
12 We flag narrowing conversions from:
13 - an integer to a narrower integer (e.g. ``char`` to ``unsigned char``)
14 if WarnOnIntegerNarrowingConversion Option is set,
15 - an integer to a narrower floating-point (e.g. ``uint64_t`` to ``float``)
16 if WarnOnIntegerToFloatingPointNarrowingConversion Option is set,
17 - a floating-point to an integer (e.g. ``double`` to ``int``),
18 - a floating-point to a narrower floating-point (e.g. ``double`` to ``float``)
19 if WarnOnFloatingPointNarrowingConversion Option is set.
22 - All narrowing conversions that are not marked by an explicit cast (c-style or
23 ``static_cast``). For example: ``int i = 0; i += 0.1;``,
24 ``void f(int); f(0.1);``,
25 - All applications of binary operators with a narrowing conversions.
26 For example: ``int i; i+= 0.1;``.
28 Arithmetic with smaller integer types than ``int`` trigger implicit conversions,
29 as explained under `"Integral Promotion" on cppreference.com
30 <https://en.cppreference.com/w/cpp/language/implicit_conversion>`_.
31 This check diagnoses more instances of narrowing than the compiler warning
32 `-Wconversion` does. The example below demonstrates this behavior.
36 // The following function definition demonstrates usage of arithmetic with
37 // integer types smaller than `int` and how the narrowing conversion happens
39 void computation(short argument1, short argument2) {
40 // Arithmetic written by humans:
41 short result = argument1 + argument2;
42 // Arithmetic actually performed by C++:
43 short result = static_cast<short>(static_cast<int>(argument1) + static_cast<int>(argument2));
46 void recommended_resolution(short argument1, short argument2) {
47 short result = argument1 + argument2;
48 // ^ warning: narrowing conversion from 'int' to signed type 'short' is implementation-defined
50 // The cppcoreguidelines recommend to resolve this issue by using the GSL
51 // in one of two ways. Either by a cast that throws if a loss of precision
53 short result = gsl::narrow<short>(argument1 + argument2);
54 // Or it can be resolved without checking the result risking invalid results.
55 short result = gsl::narrow_cast<short>(argument1 + argument2);
57 // A classical `static_cast` will silence the warning as well if the GSL
59 short result = static_cast<short>(argument1 + argument2);
65 .. option:: WarnOnIntegerNarrowingConversion
67 When `true`, the check will warn on narrowing integer conversion
68 (e.g. ``int`` to ``size_t``). `true` by default.
70 .. option:: WarnOnIntegerToFloatingPointNarrowingConversion
72 When `true`, the check will warn on narrowing integer to floating-point
73 conversion (e.g. ``size_t`` to ``double``). `true` by default.
75 .. option:: WarnOnFloatingPointNarrowingConversion
77 When `true`, the check will warn on narrowing floating point conversion
78 (e.g. ``double`` to ``float``). `true` by default.
80 .. option:: WarnWithinTemplateInstantiation
82 When `true`, the check will warn on narrowing conversions within template
83 instantiations. `false` by default.
85 .. option:: WarnOnEquivalentBitWidth
87 When `true`, the check will warn on narrowing conversions that arise from
88 casting between types of equivalent bit width. (e.g.
89 `int n = uint(0);` or `long long n = double(0);`) `true` by default.
91 .. option:: IgnoreConversionFromTypes
93 Narrowing conversions from any type in this semicolon-separated list will be
94 ignored. This may be useful to weed out commonly occurring, but less commonly
95 problematic assignments such as `int n = std::vector<char>().size();` or
96 `int n = std::difference(it1, it2);`. The default list is empty, but one
97 suggested list for a legacy codebase would be
98 `size_t;ptrdiff_t;size_type;difference_type`.
100 .. option:: PedanticMode
102 When `true`, the check will warn on assigning a floating point constant
103 to an integer value even if the floating point value is exactly
104 representable in the destination type (e.g. ``int i = 1.0;``).
110 - What does "narrowing conversion from 'int' to 'float'" mean?
112 An IEEE754 Floating Point number can represent all integer values in the range
113 [-2^PrecisionBits, 2^PrecisionBits] where PrecisionBits is the number of bits in
116 For ``float`` this would be [-2^23, 2^23], where ``int`` can represent values in
117 the range [-2^31, 2^31-1].
119 - What does "implementation-defined" mean?
121 You may have encountered messages like "narrowing conversion from 'unsigned int'
122 to signed type 'int' is implementation-defined".
123 The C/C++ standard does not mandate two's complement for signed integers, and so
124 the compiler is free to define what the semantics are for converting an unsigned
125 integer to signed integer. Clang's implementation uses the two's complement