Indeed, there is a compelling reason to avoid using these features - they are easy to misuse, resulting in programs that are harder to read and understand instead of easier to understand. In most cases, the features are also redundant - there are other ways of accomplishing the same end. Why have two ways of doing the same thing? Why not stick with the simpler one?
I do not use any of the following features in Nachos. If you use them, caveat hacker.
>>) for class objects.
This is dangerous at best ("exactly which implementation of '+' does
this refer to?"), and when used in non-intuitive ways, a
source of great confusion, made worse by the fact that C++ does
implicit type conversion, which can affect which operator
is invoked. Unfortunately, C++'s I/O facilities
make heavy use of operator overloading and references, so you
can't completely escape them, but think twice before you redefine
'+' to mean "concatenate these two strings".
The best way to avoid runaway pointers is (no surprise) to be very careful when using pointers. Instead of iterating through an array with pointer arithmetic, use a separate index variable, and assert that the index is never larger than the size of the array. Optimizing compilers have gotten very good, so that the generated machine code is likely to be the same in either case.
Even if you don't use pointer arithmetic, it's still easy (easy is bad in this context!) to have an off-by-one errror that causes your program to step beyond the end of an array. How do you fix this? Define a class to contain the array and its length; before allowing any access to the array, you can then check whether the access is legal or in error.
In addition, on some 64 bit machines, such as the Alpha, it is no longer the case that the size of an integer is the same as the the size of a pointer. If you cast between pointers and integers, you are also writing highly non-portable code.
if (x = y) {
...
Was the intent really x == y? After all, it's pretty easy
to mistakenly leave off the extra equals sign. By never using
assignment within a conditional, you can tell by code inspection
whether you've made a mistake.