44<qhelp >
55<overview >
66<p >
7- Testing for signed integer overflow by adding a
8- two signed values together and then comparing the result to one
9- of the values is ill-formed since the overflow check is undefined.
10- The comparison may produce an unintended result, or may be deleted
11- by the compiler entirely.
7+ When checking for integer overflow, one often writes tests like
8+ <code >a + b < a</code >. This works fine if <code >a</code > or
9+ <code >b</code > are unsigned integers, since any overflow in the addition
10+ will cause the value to simply "wrap around". However, using
11+ <i >signed</i > integers is problematic because signed overflows have undefined
12+ behavior according to the C and C++ standards. If the addition overflows
13+ and has an undefined result, the comparison will likewise be undefined;
14+ it may produce an unintended result, or may be deleted entirely by an
15+ optimizing compiler.
1216</p >
1317</overview >
1418<recommendation >
1519<p >
16- When checking for overflow, make sure that <code >unsigned</code > values are used.
20+ When checking for overflow by adding two values, first make sure that <code >a</code >
21+ or <code >b</code > are (converted into) unsigned values, unless it is
22+ certain that the signed addition cannot overflow.
1723</p >
1824</recommendation >
1925<example >
2026<p >
2127In the following example, even though <code >delta</code > has been declared
2228<code >unsigned short</code >, C/C++ type promotion rules require that its
2329type is promoted to the larger type used in the addition and comparison,
24- namely a <code >signed int</code >. As a result, the entire expression is
25- evaluated using <code >signed</code > integers and may overflow, and hence
26- is undefined.
30+ namely a <code >signed int</code >. Addition is performed on
31+ signed integers, and may have undefined behavior if an overflow occurs.
32+ As a result, the entire (comparison) expression may also have an undefined
33+ result.
2734</p >
2835<sample src =" SignedOverflowCheck-bad1.cpp" />
2936<p >
@@ -39,21 +46,20 @@ hold true, which likely is not what the programmer intended. (see also the
3946<sample src =" SignedOverflowCheck-bad2.cpp" />
4047<p >
4148The following example builds upon the previous one. Again, we have two
42- <code >unsigned short</code > values getting promoted to a wider type. However,
43- since <code >delta</code > is explicitly cast to an <code >unsigned</code > type,
44- <code >n1</code > (on both sides of the comparison) is promoted to
45- <code >unsigned int</code > as well. Since we are now operating on
46- <code >unsigned</code > values, the overflow check is defined and supported by
47- standard C/C++.
49+ <code >unsigned short</code > values getting promoted to a wider type, resulting
50+ in a comparison that always succeeds (since there is no overflow). To
51+ test whether we have an <code >unsigned short</code > overflow, we cast the
52+ left-hand side to it, causing the right-hand side to remain an <code >unsigned
53+ short</code > as well.
4854</p >
4955<sample src =" SignedOverflowCheck-good1.cpp" />
5056<p >
51- In the next example, a value of type <code >signed int</code > is
52- added to a value of type < code >unsigned int</ code >. Because
53- the types are of the same size, C/C++ conversion rules dictate that
54- <code >unsigned int </code > is chosen as the overall type of the addition
55- operation. The entire expression is evaluated using <code >unsigned</code >
56- values, which is allowed and defined behavior per the C/C++ standard.
57+ In the next example, we have two <code >signed int</code > values that we
58+ wish to add together. Adding them "as-is" opens the possibility of
59+ a signed integer overflow, the results of which are undefined.
60+ By casting one of the operands to <code >unsigned</code >, the entire
61+ expression is evaluated using <code >unsigned</code >
62+ values, which is defined behavior per the C/C++ standard.
5763</p >
5864<sample src =" SignedOverflowCheck-good2.cpp" />
5965</example >
0 commit comments