1
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int count=0;
    char c=127;

    do
      count++;
    while(c++);
    printf("count=%d ",count);
    return 0;
}

Can anybody explain to me why after the first loop, the value of c will become to -128?

Dave Nguyen
  • 129
  • 1
  • 1
  • 8
  • Because `char` is an 8-bit signed type. Using 2s complement, 127 is represented as 0x7F, and -128 is represented as 0x80. When incrementing 0x7F (127), we get 0x80 (-128). – barak manos Sep 21 '16 at 11:02
  • 1
    Possible duplicate of [Behavior of increment operator at bounds for char type](http://stackoverflow.com/questions/9016741/behavior-of-increment-operator-at-bounds-for-char-type) – msc Sep 21 '16 at 11:04
  • @barakmanos: [`char` actually has undefined signedness by the standard.](http://stackoverflow.com/a/2054941/364696). That's why I was careful to note in my answer that this was a choice by his compiler. It's usually signed, but compiler flags can change it to unsigned, and either interpretation is standard legal. – ShadowRanger Sep 21 '16 at 11:08
  • @ShadowRanger: I actually think it's a shame that the language standard does not impose `sign`/`unsigned` next to every integral type, and on the other hand, allows declarations like `unsigned` (synonymous to `unsigned int`), `short int` (synonymous to `short`), and several other different forms like `long int`, `long long int`, etc. Not sure why they didn't take their time to come up with a minimal and concise set of (simple) rules, and in exchange, left all this ambiguity behind... – barak manos Sep 21 '16 at 11:11
  • 1
    Should this be read as "while there is c++, no good outcome is possible"? :) – Lundin Sep 21 '16 at 11:49
  • *Can anybody explain to me why after the first loop, the value of c will become to -128?*: how do you know that? I see `count=130` whether `char` is signed or not, albeit not guaranteed. – chqrlie Jul 18 '17 at 08:29

3 Answers3

7

Because your compiler defaults char to signed char. So the range of values for it is -128 to 127, and incrementing 127 is triggering wraparound. If you want to avoid this, be explicit, and declare your variable as unsigned char.

Mind you, to do this correctly, you also want to change the printf; you're printing as a signed int value (%d); to be 100% type correct, you'd want to match types, so the format code should be %hhd for a signed char, or %hhu for an unsigned char. %d will work due to promotion rules with varargs, but it's a bad habit to just use %d all the time; when you print an unsigned with %d, your system will likely succeed, but it will show large values as being negative, confusing you.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • 1
    Please note that signed integer overflow is actually undefined behavior. Wrap-around is not guaranteed. The program might as well halt and catch fire or seemingly work as expected. – Lundin Sep 21 '16 at 11:55
  • [AFAIK](http://stackoverflow.com/a/8010063/4944425), not even a two's complement representation is guarateed by the standard... – Bob__ Sep 21 '16 at 14:25
2

Another easy explanation of this problem

This situation is known as overflow of signed char. Range of unsigned char is -128 to 127. If we will assign a value greater than 127 then value of variable will be changed to a value if we will move clockwise direction as shown in the figure according to number. If we will assign a number which is less than -128 then we have to move in anti-clockwise direction.

When variable value is 127 then it's ok. But if variable value increment by 1 then clock wise increment also 1 and it's position value -128. So your output is -128.

Demo Image

Demo Link

A.A Noman
  • 5,244
  • 9
  • 24
  • 46
1

try using unsigned char to count up to 255

CS_EE
  • 399
  • 2
  • 10