Programming safety means that programs maintain a minimum coherency and fail in a graceful way. In other words, no core dumps. This forbids accessing unitialized pointers or discarded objects, unrestricted pointer arithmetic and unchecked array indexing (thus accessing outside an array). Indeed, each of these errors may lead to memory corruption and unpredictible behavior. Fortunately, on an adequate operating system, the damages caused by unsafe programs are usually limited to crashing the faulty program, using up all available memory and CPU time and messing up with the program owner's files.
Program development, testing and debugging benefit from programming safety. Indeed, without such coherency checks, many errors may remain undetected for some time. Even when an error is detected, its symptoms may appear far from the original cause, making it very hard to locate. There is however a price to pay, in performance and memory, for such checks. Each pointer and array access may require a test. Garbage collection is also mandatory. This may amount to something like a 20%overhead. However, promising work is under way to detect when such checks are unnecessary and can be optimized out. Some programming environments also offer a compilation option to leave or remove such checks.
Nevertheless, there are languages where the semantics are based on pointer arithmetic and such checks are close to impossible in the general case. In C++, for instance, a safe subset has been defined for which checks may be added to provide safety. Some C and C++ environments offer debugging tools that will catch a number of such errors; checks are added to all accesses in order to verify that the address belongs to a live object, which may detect using discarded objects or accessing uninitialized pointers.
There are however cases where unsafe operations are required. A possible example is the core of the run time libraries that implement garbage collection. Another example is interacting with library procedures implemented in an unsafe programming language. Modula-3 offers an interesting solution to this problem. When a module is prominently marked as UNSAFE, which should discourage careless use, some unsafe operations such as pointer arithmetic are allowed. Experience shows that, outside the low level libraries, few Modula-3 programs ever need unsafe operations. This allows Modula-3 to remain a safe programming language while not forcing programmers to use another language for exceptional cases of unsafe low level programming.