Implementation-defined behavior and Undefined behavior
The C++ standard is very specific about the effects of various constructs, and in particular you should always be aware of these categories of trouble:
- Undefined behavior means that there are absolutely no guarantees given. The code could work, or it could set fire to your harddrive or make demons fly out your nose. As far as the C++ language is concerned, absolutely anything might happen. In practical terms, this generally means that you have an unrecoverable bug. If this happens, you can't really trust anything about your application (because one of the effects of this undefined behavior might just have been to mess up the memory used by the rest of your app). It's not even required to be consistent, so simply running the program twice might give different results. It may depend on the phases of the moon, the color of the shirt you're wearing or absolutely anything else.
- Unspecified behavior means that the program must do something sane and consistent, but it is not required to document this.
- Implementation-defined behavior is similar to unspecified, but must also be documented by the compiler writers. An example of this is the result of a
reinterpret_cast
. usually, it simply changes the type of a pointer, without modifying the address, but the mapping is actually implementation-defined, so a compiler could map to a completely different address, as long as it documented this choice. Another example is the size of an int. The C++ standard doesn't care if it is 2, 4 or 8 bytes, but it must be documented by the compiler
But common for all of these is that they're best avoided. When possible, stick with behavior that is 100% specified by the C++ standard itself. That way, you're guaranteed portability.
You often have to rely on some implementation-defined behavior as well. It may be unavoidable, but you should still pay attention to it, and be aware that you're relying on something that may change between different compilers.
Undefined behavior, on the other hand, should always be avoided. In general, you should just assume that it makes your program explode in one way or another.