|
From: | David Brown |
Subject: | Re: [lwip-devel] LWIP_U32_DIFF is unnecessarily complex |
Date: | Wed, 23 Nov 2011 14:37:07 +0100 |
User-agent: | Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20111105 Thunderbird/8.0 |
On 23/11/2011 13:36, Mason wrote:
Mike Kleshov wrote:Mason wrote:I think your question is equivalent to asking whether the following statement is well-defined. unsigned n = -42; /*** -42 has type int ***/ 3.2 CONVERSIONS 3.2.1.2 Signed and unsigned integersNo, it isn't. There is no type conversion involved in (a - b) where both a and b are u32_t.Mike, It is correct that the expression (a - b) has type unsigned int if both 'a' and 'b' have type unsigned int (AFAIU). The way I understand it, since the result of (a-b) may not fit in an unsigned int, the value must be "reduced" to an unsigned int, "reduced" being defined as "the non-negative remainder on division by the number one greater than the largest unsigned number that can be represented in the type with smaller size." (type with smaller size being unsigned int in this case) e.g. -42 = -1 x 4294967296 + 4294967254 quotient = -1 remainder = 4294967254 I agree that there is room for confusion, and I looked for a relevant Defect Report, but could not find one.
As far as I understand it, unsigned arithmetic in C is defined to use 2's complement arithmetic (unlike signed arithmetic, which may use something else). "a - b" is thus defined as "a + (-b)", where "+" is defined modulo 2^32 (or 2^16, etc., depending on the size of the types). And "-b" is defined as "~b + 1".
This has exactly the same effect as you describe here.Since unsigned addition cannot overflow, nor can unsigned subtraction. So the macro LWIP_U32_DIFF should be defined simply:
#define LWIP_U32_DIFF(a, b) ((a) - (b)) assuming the comment "'a' is expected to be higher than 'b'" is valid. If that comment is not valid, a better definition would be: #define LWIP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : ((b) - (a)))
[Prev in Thread] | Current Thread | [Next in Thread] |