2

Can you explain this moment? Why unsigned int doesn't convert to signed int.

signed int a = 100;
unsigned int b = 4294967295;
a-b; /// Why 'a' will be convert to unsigned? Explain pls
too honest for this site
  • 12,050
  • 4
  • 30
  • 52
MaximPro
  • 563
  • 8
  • 21
  • 9
    Because that's what the language says. – user253751 Feb 15 '17 at 23:15
  • 1
    http://port70.net/~nsz/c/c11/n1570.html#6.3.1.8p1 – Petr Skocik Feb 15 '17 at 23:17
  • 2
    Aside to the `a-b` issue: `4294967295` is likely not an `int`, nor `unsigned`, but a `long` or `long long` and gets converted to an `unsigned`. – chux - Reinstate Monica Feb 15 '17 at 23:18
  • BTW: `a-b;` :statement has no effect: can be optimised out. – wildplasser Feb 15 '17 at 23:20
  • 1
    @Chux why 4294967295 is not unsigned? – MaximPro Feb 15 '17 at 23:21
  • @chux The question is not answered because the question is about why this rule was adopted in the Standard. – Vlad from Moscow Feb 15 '17 at 23:24
  • @jenesaisquoi 4294967295 is UINT_MX in his system. – Vlad from Moscow Feb 15 '17 at 23:26
  • 3
    @MaximPro: 4294967295 is a decimal constant, and the types of decimal constants are the smallest of `int`, `long int` and `long long int` that will hold the value (C11 §6.4.4.1 Integer constants, ¶5). If the value was written 0xFFFFFFFF, then it would probably be an `unsigned int` (assuming 32-bit `int` type). – Jonathan Leffler Feb 15 '17 at 23:26
  • 1
    @MaximPro if you have 32-bit `int` the value `4294967295` *cannot* be converted to `int` because it is outside of its range. – Weather Vane Feb 15 '17 at 23:29
  • @immibis And he asks why did the standard adopt this rule instead of converting to the signed type? – Vlad from Moscow Feb 15 '17 at 23:30
  • @WeatherVane Strictly speaking INT_MIN is also outside the range of non-negative numbers.:) – Vlad from Moscow Feb 15 '17 at 23:33
  • 2
    @VladfromMoscow: But there's no useful answer other than 'K&R 1st Edition said so', and it was implemented because it seemed sensible to do it that way when the `unsigned` qualifier was added to C, somewhere in the early to mid 70s. – Jonathan Leffler Feb 15 '17 at 23:35
  • @VladfromMoscow which is why `limits.h` has `#define INT_MIN (-2147483647 - 1)`. – Weather Vane Feb 15 '17 at 23:35
  • 1
    @MaximPro Are you asking what the conversion rule is with mixed `unsigned` and. `int`? Or are you asking why the standard specified that `unsigned` should be used instead of `int` in mixed code? – chux - Reinstate Monica Feb 15 '17 at 23:41
  • @Chux second :) – MaximPro Feb 15 '17 at 23:44
  • @JonathanLeffler that's if C11 is in use - many people still use compilers defaulting to C89 mode, or even non-standard mode. – M.M Feb 16 '17 at 00:07
  • @M.M: That's the standard I quoted from. C99 effectively (if not literally) says the same, and in the same section number. C89 doesn't mention `long long`, of course (and the section number is different — §6.1.3.2): _The type of an integer constant is the first of the corresponding list in which its value can be represented. Unsuffixed decimal `int`, `long int`, `unsigned long int`: …_ It's interesting that the 'unsigned' alternative is lost in the C99 and C11 standards. – Jonathan Leffler Feb 16 '17 at 00:12
  • 1
    @MaximPro Guess: At the time (1970s), there were 3 flavors of `signed int` in common usage: 2'complement, 1's complement, sign-magnitude. Conversion `unsigned` to `int` is not easy to specify in a way that all 3 should behave in a common way that is easy for various platforms to implement. So `unsigned` to `int` conversion is implementation-defined Conversion the other way is well defined and it goes to the one and only representation (aside from width) **and does not favor** one representation. Converting to `unsigned` with mixed `int/unsigned`, code uses well defined neutral representation – chux - Reinstate Monica Feb 16 '17 at 00:22
  • Conversion is not the same as casting. Don't use unrelated tags. – too honest for this site Feb 16 '17 at 11:18

0 Answers0