One possibility is to use a language that has arbitrarily sized integers that never overflow / underflow.
Otherwise, if this is something you're really concerned about, and if your language allows it, write a wrapper class that acts like an integer, but checks every operation for overflow. You could even have it do the check on debug builds, and leave things optimized for release builds. In a language like C++, you could do this, and it would behave almost exactly like an integer for release builds, but for debug builds you'd get full run-time checking.
class CheckedInt
{
private:
int Value;
public:
// Constructor
CheckedInt(int src) : Value(src) {}
// Conversions back to int
operator int&() { return Value; }
operator const int &() const { return Value; }
// Operators
CheckedInt operator+(CheckedInt rhs) const
{
if (rhs.Value < 0 && rhs.Value + Value > Value)
throw OverflowException();
if (rhs.Value > 0 && rhs.Value + Value < Value)
throw OverflowException();
return CheckedInt(rhs.Value + Value);
}
// Lots more operators...
};
Edit:
Turns out someone is doing this already for C++ - the current implementation is focused for Visual Studio, but it looks like they're getting support for gcc as well.