The following code crashes C++ with a runtime error:
#include
using namespace std;
int main() {
string s = \"aa\";
for (int i = 0; i
for
loopMost people here seem unable to reproduce the crash—myself included—and it looks like the other answers here are based on the assumption that you left out some important code in the body of the for
loop, and that the missing code is what is causing your crash.
If you are using i
to access memory (presumably characters in the string) in the body of the for
loop, and you left that code out of your question in an attempt to provide a minimal example, then the crash is easily explained by the fact that s.length() - 3
has the value SIZE_MAX
due to modular arithmetic on unsigned integer types. SIZE_MAX
is a very big number, so i
will keep getting bigger until it is used to access an address that triggers a segfault.
However, your code could theoretically crash as-is, even if the body of the for
loop is empty. I am unaware of any implementations that would crash, but maybe your compiler and CPU are exotic.
The following explanation does not assume that you left out code in your question. It takes on faith that the code you posted in your question crashes as-is; that it isn't an abbreviated stand-in for some other code that crashes.
Your first program crashes because that is its reaction to undefined behavior in your code. (When I try running your code, it terminates without crashing because that is my implementation's reaction to the undefined behavior.)
The undefined behavior comes from overflowing an int
. The C++11 standard says (in [expr] clause 5 paragraph 4):
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
In your example program, s.length()
returns a size_t
with value 2. Subtracting 3 from that would yield negative 1, except size_t
is an unsigned integer type. The C++11 standard says (in [basic.fundamental] clause 3.9.1 paragraph 4):
Unsigned integers, declared
unsigned
, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.4646) This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.
This means that the result of s.length() - 3
is a size_t
with value SIZE_MAX
. This is a very big number, bigger than INT_MAX
(the largest value representable by int
).
Because s.length() - 3
is so big, execution spins in the loop until i
gets to INT_MAX
. On the very next iteration, when it tries to increment i
, the result would be INT_MAX
+ 1 but that is not in the range of representable values for int
. Thus, the behavior is undefined. In your case, the behavior is to crash.
On my system, my implementation's behavior when i
is incremented past INT_MAX
is to wrap (set i
to INT_MIN
) and keep going. Once i
reaches -1, the usual arithmetic conversions (C++ [expr] clause 5 paragraph 9) cause i
to equal SIZE_MAX
so the loop terminates.
Either reaction is appropriate. That is the problem with undefined behavior—it might work as you intend, it might crash, it might format your hard drive, or it might cancel Firefly. You never know.
As with the first program, s.length() - 3
is a size_t
type with value SIZE_MAX
. However, this time the value is being assigned to an int
. The C++11 standard says (in [conv.integral] clause 4.7 paragraph 3):
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.
The value SIZE_MAX
is too big to be representable by an int
, so len
gets an implementation-defined value (probably -1, but maybe not). The condition i < len
will eventually be true regardless of the value assigned to len
, so your program will terminate without encountering any undefined behavior.