The difference is that in the unsigned case you get a seemingly plausible value, and in the signed case you get a negative value which you can be sure is wrong. This is the problem.
In some languages, the signed version is undefined behavior. You may get a negative value, INT_MAX / 2, or an error. Or the compiler may detect the undefined behavior, which according to the standard cannot happen, and mutilate your code in unexpected ways.
In some languages, the signed version is undefined behavior. You may get a negative value, INT_MAX / 2, or an error. Or the compiler may detect the undefined behavior, which according to the standard cannot happen, and mutilate your code in unexpected ways.