You could imagine bounds being baked into the types and checked at compile time.
int{0..10} foo = 4
int{0..10} bar = 5
int{0..10} buzz = foo+bar // ERR: 10+10 potentially > 10
int{0..10} boom = wrapping_add(foo, bar) // OK
int{0..100} sum = foo+bar // OK
There are tools which can do this, for example Code Contracts in C#. It becomes rather tedious and verbose so is something usually only left for very safety critical code.
This could be useful in C for some situations. That said, the above is completely useless if just only one of those values (ranges or assignments) is dynamic: you'll be back to carefully (and manually) checking you don't overflow.*
*edit: unless your compiler automatically emits instructions to do the check at runtime; a thing that won't happen (and I don't want) in C.