difference of unsigned integer - standard supported way to get signed result?

Bathsheba's answer is correct but for completeness here are two more ways (which happen to work in C++ as well):

uint32_t u_diff = timestamp1 - timestamp2;
int32_t difference;
memcpy(&difference, &u_diff, sizeof difference);

and

uint32_t u_diff = timestamp1 - timestamp2;
int32_t difference = *(int32_t *)&u_diff;

The latter is not a strict aliasing violation because that rule explicitly allows punning between signed and unsigned versions of an integer type.


The suggestion:

int32_t difference = (int32_t)(timestamp1 - timestamp2);

will work on any actual machine that exists and offers the int32_t type, but technically is not guaranteed by the standard (the result is implementation-defined).


You can use a union type pun based on

typedef union
{
    int32_t _signed;
    uint32_t _unsigned;
} u;

Perform the calculation in unsigned arithmetic, assign the result to the _unsigned member, then read the _signed member of the union as the result:

u result {._unsigned = timestamp1 - timestamp2};
result._signed; // yields the result

This is portable to any platform that implements the fixed width types upon which we are relying (they don't need to). 2's complement is guaranteed for the signed member and, at the "machine" level, 2's complement signed arithmetic is indistinguishable from unsigned arithmetic. There's no conversion or memcpy-type overhead here: a good compiler will compile out what's essentially standardese syntactic sugar.

(Note that this is undefined behaviour in C++.)