I don\'t quite understand why I don\'t get a division by zero exception:
int d = 0;
d /= d;
I expected
Note that you can have your code generate a C++ exception in this (and other cases) by using boost safe numerics. https://github.com/boostorg/safe_numerics
C++ does not have a "Division by Zero" Exception to catch. The behavior you're observing is the result of Compiler optimizations:
d == 0
) must not happend / d
must always equal 1.We can force the compiler to trigger a "real" division by zero with a minor tweak to your code.
volatile int d = 0;
d /= d; //What happens?
So now the question remains: now that we've basically forced the compiler to allow this to happen, what happens? It's undefined behavior—but we've now prevented the compiler from optimizing around this undefined behavior.
Mostly, it depends on the target environment. This will not trigger a software exception, but it can (depending on the target CPU) trigger a Hardware Exception (an Integer-Divide-by-Zero), which cannot be caught in the traditional manner a software exception can be caught. This is definitely the case for an x86 CPU, and most other (but not all!) architectures.
There are, however, methods of dealing with the hardware exception (if it occurs) instead of just letting the program crash: look at this post for some methods that might be applicable: Catching exception: divide by zero. Note they vary from compiler to compiler.
Just to complement the other answers, the fact that division by zero is undefined behavior means that the compiler is free to do anything in cases where it would happen:
0 / 0 == 1
and optimize accordingly. That's effectively what it appears to have done here.0 / 0 == 42
and set d
to that value.d
is indeterminate, and thus leave the variable uninitialized, so that its value will be whatever happened to be previously written into the memory allocated for it. Some of the unexpected values observed on other compilers in the comments may be caused by those compilers doing something like this.d
was not known at compile time, the compiler could still assume that it's never zero and optimize the code accordingly. In the particular case of the OP's code, this is effectively indistinguishable from the compiler just assuming that 0 / 0 == 1
, but the compiler could also, for example, assume that the puts()
in if (d == 0) puts("About to divide by zero!"); d /= d;
never gets executed! The behaviour of integer division by zero is undefined by the C++ standard. It is not required to throw an exception.
(Floating point division by zero is also undefined but IEEE754 defines it.)
Your compiler is optimising d /= d
to, effectively d = 1
which is a reasonable choice to make. It's allowed to make this optimisation since it's allowed to assume there is no undefined behaviour in your code - that is d
cannot possibly be zero.