为什么在C ++中未定义256个签名字符

时间:2012-11-26 17:02:45

标签: c++ char signed

阅读C ++ Primer第5版的书,我注意到signed char的值256未定义。 我决定尝试一下,我看到std::cout没有为char变量工作。 (没有印刷)。

但在C上,同样的事情 signed char c = 256; 会为0提供值char c

我试过搜索但没有找到任何东西。

有人可以向我解释为什么C ++会出现这种情况?

编辑:我知道256是2个字节,但是为什么与C中的相同,发生在C ++中?

6 个答案:

答案 0 :(得分:11)

这本书非常不正确。

中没有未定义的行为
signed char c = 256;

256int类型的整数文字。要使用它初始化signed char,它将转换为signed char(§8.5[dcl.init] /17.8;所有引用都转到N4140)。此转换受§4.7[conv.integral]:

的约束
  

1整数类型的prvalue可以转换为prvalue   另一种整数类型。可以使用无范围枚举类型的prvalue   转换为整数类型的prvalue。

     

2如果目的地类型是无符号的,[...]

     

3如果目标类型已签名,则值可以保持不变   以目的地类型(和位字段宽度)表示;   否则,该值是实现定义的。

如果signed char不能代表256,那么转换会产生类型signed char的实现定义值,然后用于初始化c。这里没有什么不明确的。


当人们说“签名溢出是UB”时,他们通常是指§5[expr] / p4中的规则:

  

如果在评估表达式期间,结果不是   在数学上定义或不在可表示值的范围内   它的类型,行为是未定义的。

这会渲染类似INT_MAX + 1的UB表达式 - 操作数都是int s,因此结果的类型也是int,但该值超出了可表示值的范围。此规则不适用于此处,因为唯一的表达式为256,其类型为int,而256显然位于int的可表示值范围内。

答案 1 :(得分:6)

编辑:见T.C.的答案如下。它更好。

在C ++和C中未定义有符号整数溢出。在大多数实现中,signed charSCHAR_MAX的最大值为127,因此将256放入其中会溢出它。大多数情况下,你会看到数字只是环绕(到0),但这仍然是未定义的行为。

答案 2 :(得分:3)

您看到coutprintf之间存在差异。输出带有cout的字符时,如果没有数字表示,则会得到一个字符。在这种情况下,角色为NUL,不会出现在屏幕上。

请参阅http://ideone.com/7n6Lqc

上的示例

答案 3 :(得分:2)

char通常为8 bitsbyte,因此可以保留2^8个不同的值。如果是unsigned,则从0升级到255,否则,signed-128127

答案 4 :(得分:1)

unsigned char值(通常是迂腐的)是0到255.有256个值,1个字节可以保存。

如果出现溢出(通常),则使用模256的值作为其他整数类型的模MAX + 1

答案 5 :(得分:0)

@Pubby我不知道C / C ++标准是否在有符号整数溢出时定义了行为,但是gcc似乎并不总是将(x

以下代码生成输出:1 0 0 0(32位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);