10

What happens if I do something like this:

unsigned int u;
int s;

...
s -= u;

What's the expected behavior of this:

1) Assuming that the unsigned integer isn't too big to fit in the signed integer?

2) Assuming that the unsigned integer would overflow the signed integer?

Thanks.

Colen
  • 12,918
  • 21
  • 74
  • 101
  • possible duplicate of [signed to unsigned conversion in C - is it always safe?](http://stackoverflow.com/questions/50605/signed-to-unsigned-conversion-in-c-is-it-always-safe) – Prasoon Saurav Mar 16 '11 at 17:09
  • Not a complete duplicate. That question had the last assignment into an `unsigned` variable, so the arithmetic is the same but the last assignment is different. – David Thornley Mar 16 '11 at 17:17
  • Also worth to have a look at: [*Is unsigned integer subtraction defined behavior?*](http://stackoverflow.com/q/7221409/1168156) :) – LihO Feb 24 '13 at 16:38

2 Answers2

14

In general, consult 5/9 in the standard.

In your example, the signed value is converted to unsigned (by taking it mod UINT_MAX+1), then the subtraction is done modulo UINT_MAX+1 to give an unsigned result.

Storing this result back as a signed value to s involves a standard integral conversion - this is in 4.7/3. If the value is in the range of signed int then it is preserved, otherwise the value is implementation-defined. All the implementations I've ever looked at have used modulo arithmetic to push it into the range INT_MIN to INT_MAX, although as Krit says you might get a warning for doing this implicitly.

"Stunt" implementations that you'll probably never deal with might have different rules for unsigned->signed conversion. For example if the implementation has sign-magnitude representation of signed integers, then it's not possible to always convert by taking modulus, since there's no way to represent +/- (UNIT_MAX+1)/2 as an int.

Also relevant is 5.17/7, "The behavior of an expression of the form E1 op= E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once". This means that in order to say that the subtraction is done in the unsigned int type, all we need to know is that s - u is done in unsigned int: there's no special rule for -= that arithmetic should be done in the type of the LHS.

Steve Jessop
  • 265,622
  • 35
  • 449
  • 690
  • Just a reminder that the "implementation defined result" could be an "implementation defined signal". (The C standard is much clearer in this regard.) In practice, you'll get the correct results on a two's complement machine, wrong results elsewhere. – James Kanze Mar 16 '11 at 17:20
  • @James: I think that's a deliberate difference between C++ and C, then. The C++ wording is quite clear, "the value is implementation-defined". It doesn't say, "the behavior is implementation-defined", which would permit a signal. – Steve Jessop Mar 16 '11 at 17:23
-1

u is recast as a signed integer and subtracted from s. Ultimately the casting doesn't make any difference. One set of bits is subtracted from the other and the result goes into s.

phkahler
  • 5,622
  • 1
  • 21
  • 31