-1

I had been learning C and came across topic called Cyclic Nature of Data Type in C.

It is like example

char c=125;
c=c+10;
printf("%d",c);

The output is -121. the logic given was

125+1= 126
125+2= 127
125+3=-128
125+4=-127
125+5=-126
125+6=-125
125+7=-124
125+8=-123
125+9=-122
125+10=-121

This is due to cyclic nature if char datatype. Y does Char exhibit cyclic nature?? How is it possible to char??

shashank
  • 400
  • 8
  • 25
  • 1
    I don't know about Cyclic Nature of Data Type thing that you mentioned. The explanation to what you describe is called overflow – marcadian Aug 06 '14 at 08:01

3 Answers3

4

On your system char is signed char. When a signed integral type overflows, the result is undefined. It may or may not be cyclic. Although on most of the machines performing 2's complement arithmetic, you may observe this as cyclic.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
1

The char data type is signed type, as per your implementation. As such it can store values in range: -128 to 127. When you store a value greater than 127, you would end up with a value that might be in negative or positive number, depending on how large is the value stored and what kind of platform you are working on. Signed integer overflow is undefined behavior in C and then not at all unsigned numbers are guaranteed to wrap around.

askmish
  • 6,464
  • 23
  • 42
  • 2
    char type may be signed or unsigned (implementation dependent) and minimum range of signed char is `-127 to 127` which is `-128 to 127` on most of the system working in 2s complement system. – Mohit Jain Aug 06 '14 at 08:04
  • @MohitJain The char data type is implementation defined, but as per OP's question and code output, its clear that its signed in his platform. Still updated the answer to reflect this construct. – askmish Aug 06 '14 at 08:15
  • (+1) This is much clearer now. – Mohit Jain Aug 08 '14 at 13:08
0

char isn’t special in this regard (besides its implementation-defined signedness), all conversions to signed types usually exhibit this “cyclic nature”. However, there are undefined and implementation-defined aspects of signed overflow, so be careful when doing such things.

What happens here:

In the expression

c=c+10

the operands of + are subject to the usual arithmetic conversions. They include integer promotion, which converts all values to int if all values of their type can be represented as an int. This means, the left operand of + (c) is converted to an int (an int can hold every char value1)). The result of the addition has type int. The assignment implicitly converts this value to a char, which happens to be signed on your platform. An (8-bit) signed char cannot hold the value 135 so it is converted in an implementation-defined way 2). For gcc:

For conversion to a type of width N, the value is reduced modulo 2N to be within range of the type; no signal is raised.

Your char has a width of 8, 28 is 256, and 135 ☰ -121 mod 256 (cf. e.g. 2’s complement on Wikipedia).

You didn’t say which compiler you use, but the behaviour should be the same for all compilers (there aren’t really any non-2’s-complement machines anymore and with 2’s complement, that’s the only reasonable signed conversion definition I can think of).

Note, that this implementation-defined behaviour only applies to conversions, not to overflows in arbitrary expressions, so e.g.

int n = INT_MAX;
n += 1;

is undefined behaviour and used for optimizations by some compilers (e.g. by optimizing such statements out), so such things should definitely be avoided.

A third case (unrelated here, but for sake of completeness) are unsigned integer types: No overflow occurs (there are exceptions, however, e.g. bit-shifting by more than the width of the type), the result is always reduced modulo 2N for a type with precision N.

Related:


1 At least for 8-bit chars, signed chars, or ints with higher precision than char, so virtually always.

2 The C standard says (C99 and C11 (n1570) 6.3.1.3 p.3) “[…] either the result is implementation-defined or an implementation-defined signal is raised.” I don’t know of any implementation raising a signal in this case. But it’s probably better not to rely on that conversion without reading the compiler documentation.

Community
  • 1
  • 1
mafso
  • 5,433
  • 2
  • 19
  • 40