Why 256 for a signed char is undefined in C++

后端 未结 6 436
Happy的楠姐
Happy的楠姐 2020-12-20 03:30

Reading the C++ Primer 5th edition book, I noticed that a signed char with a value of 256 is undefined. I decided to try that, and I saw that

相关标签:
6条回答
  • 2020-12-20 04:06

    @Pubby I don't know if the C/C++ standards have defined the behavior when signed integer overflows, but gcc seems not always treat (x < x + 1) as true. the "<" operator takes signed int as operand, so x < x + 1 --> (int)x < (int)x + (int)1

    the following code produces output: 1 0 0 0 (32bit Linux + gcc)

    signed char c1, c2; 
    signed int i1, i2; 
    
    c1 = 127;
    c2 = c1 + 1;
    
    i1 = 2147483647;
    i2 = i1 + 1;
    
    printf("%d %d\n", c1 < c1 + 1, c1 < c2);
    printf("%d %d\n", i1 < i1 + 1, i1 < i2);
    
    0 讨论(0)
  • 2020-12-20 04:10

    The book is wildly incorrect. There's no undefined behavior in

    signed char c = 256;
    

    256 is an integer literal of type int. To initialize a signed char with it, it is converted to signed char (§8.5 [dcl.init]/17.8; all references are to N4140). This conversion is governed by §4.7 [conv.integral]:

    1 A prvalue of an integer type can be converted to a prvalue of another integer type. A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.

    2 If the destination type is unsigned, [...]

    3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.

    If signed char cannot represent 256, then conversion yields an implementation-defined value of type signed char, which is then used to initialize c. There is nothing undefined here.


    When people say "signed overflow is UB", they are usually referring to the rule in §5 [expr]/p4:

    If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

    This renders UB expressions like INT_MAX + 1 - the operands are both ints, so the result's type is also int, but the value is outside the range of representable values. This rule does not apply here, as the only expression is 256, whose type is int, and 256 is obviously in the range of representable values for int.

    0 讨论(0)
  • 2020-12-20 04:13

    unsigned char values is (to be pedantic, usually) is from 0 to 255. There is 256 values, that 1 byte may hold.

    If you get overflow (usually) values are used modulo 256, as other Integer type modulo MAX + 1

    0 讨论(0)
  • 2020-12-20 04:16

    A char is generally 8 bits or a byte, therefore can hold 2^8 different values. If it is unsigned, from 0 to 255 otherwise, when signed from -128 to 127

    0 讨论(0)
  • 2020-12-20 04:21

    Edit: See T.C.'s answer below. It's better.

    Signed integer overflow is undefined in C++ and C. In most implementations, the maximum value of signed char, SCHAR_MAX, is 127 and so putting 256 into it will overflow it. Most of the time you will see the number simply wrap around (to 0), but this is still undefined behavior.

    0 讨论(0)
  • 2020-12-20 04:30

    You're seeing the difference between cout and printf. When you output a character with cout you don't get the numeric representation, you get a single character. In this case the character was NUL which doesn't appear on-screen.

    See the example at http://ideone.com/7n6Lqc

    0 讨论(0)
提交回复
热议问题