There were C implementations with bounds checking or implementations that trap on use of an invalid pointer or on read of uninitialized variables etc. A large part of UB was introduced for such reasons and not for performance. The standard was (and still is) about allowing a wide range of implementations.