A few things about undefined behavior:
Firstly, the standard allows a compiler to provide implementation specific behavior in cases of undefined behavior. A prime example is that if you're writing an operating system, dereferencing a null pointer may actually make sense.
Now, on that note, the behavior is still undefined with regards to the C++ language, no matter how much implementation defined slag you drop on it.
Undefined behavior does not have to manifest its self as crashes, compiler errors, or anything of the sort.
The example my quiz used was std::cout<<a<<a++<<--a;. Why is this behavior undefined? If you look at it, it looks like it should be:
std::operator<<(a).operator<<(a++).operator(--a);, and it is. However, it is important to note something very important about parameters: The order of evaluation of function parameters is unspecified. As such they can be evaluated in ANY ORDER prior to the function being called. So, the following are all valid evaluations:
//the one you probably expectedstd::cout.operator<<(a);std::cout.operator<<(a++);std::cout.operator<<(--a);a;a++;--a;std::cout.operator<<(a);std::cout.operator<<(a);std::cout.operator<<(a);a++;a;--a;std::cout.operator<<(a);std::cout.operator<<(a);std::cout.operator<<(a);//and so on.
The point is: there are no real sequence points there that prevent a from being modified more than once between the function calls. Which is what ultimately causes the behavior to be undefined. If we had used a, b, and c then the behavior would have been perfectly well defined, although the order in which a b and c are evaluated would still be unspecified.
This is the danger of undefined behavior, it causes things to operate in ways that you don't expect or things will work as you expect until you change compiler versions, etc.
It should be noted that in C++0x they have tried to clean up a lot of the danger spots in the language, although how many of those changes will actually make it into the final standard is still unknown.