Not really. Addition and subtraction don't care about unsigned vs signed status, because overflow is identitcal in both cases.
Think of an odometer for a car with 999999 as its max number. 999,999 is equivalent to -1. So 500 + 999999 == 499 on the odometer.
A 32-bit register is simply a binary odometer, so the above concept happens with bits.
In "signed int", we print the number "999999" as "-1". With "unsigned int", we print the number "999999" as "999999". They are one-and-the-same. The only difference is your print() function.
-----
Multiplication and division change however. Your compiler tracks signed/unsigned status for idiv vs div, or mul vs imul instructions.
--------
With that being said: I think 64-bits is fine. Most computers these days are 64-bits, and those 4-extra bytes aren't very costly. Standard compression algorithms, like GZip, do a good job of finding those redundant bits and shrinking things down.
Many if not most of the embedded/long term systems are implemented in C. If a variable is declared signed, overflowing cases may and often are "optimized" away.
IIUC, GP's foo() would likely be optimized to { return true; }, and so would similar timestamp overflow checks.
The post I responded to was the opposite: about turning "signed" code (which you declare is undefined) into "unsigned" code (which you declare is fully defined).
Given this thread of subargument, making the difference between 32-bit unsigned numbers is MORE DEFINED than using signed integers.
-------
IE: If your code was correct with "int timestamp", it will be more correct with "unsigned int timestamp".
In any case, "int" or "unsigned int" based timestamp manipulation wouldn't be like the code you suggested, but instead "int difference = x - y".
In the signed integer case, "difference" is (conceptually) negative, while in the unsigned integer case, "difference" is guaranteed to have overflow. Both cases are conceptually correct with regards to the difference of timestamps.
But because the behaviour is undefined, it doesn't matter how the computer would handle it, because the compiler is free to rework it into any arbitrary sequence of instructions, including removing it altogether.
Think of an odometer for a car with 999999 as its max number. 999,999 is equivalent to -1. So 500 + 999999 == 499 on the odometer.
A 32-bit register is simply a binary odometer, so the above concept happens with bits.
In "signed int", we print the number "999999" as "-1". With "unsigned int", we print the number "999999" as "999999". They are one-and-the-same. The only difference is your print() function.
-----
Multiplication and division change however. Your compiler tracks signed/unsigned status for idiv vs div, or mul vs imul instructions.
--------
With that being said: I think 64-bits is fine. Most computers these days are 64-bits, and those 4-extra bytes aren't very costly. Standard compression algorithms, like GZip, do a good job of finding those redundant bits and shrinking things down.