一个问题:是否定义了a >> ((sizeof a) * CHAR_BIT),这是UB还是IDB?

4

1.请考虑以下内容:

unsigned int a, b;

b = a >> ((sizeof a) * CHAR_BIT);

/* or 2nd operand greater than ((sizeof a) * CHAR_BIT) */

这是定义的行为、未定义的行为还是实现相关的行为?

2. 另一个子问题:

如果 asigned int 并且它的移位小于其位长度,那么在进行有符号位移时是实现定义还是未定义行为。 在以下两种情况下:

  1. 向右移位时:a >> 5
  2. 向左移位时:a << 5

编辑 问题已编辑

1个回答

7

1.

从C99标准,第6.5.7节:

整数提升在每个操作数上执行。结果的类型是提升左操作数的类型。如果右操作数的值为负数或大于或等于提升左操作数的宽度,则行为未定义。

所以它是未定义的。

2.

来自同一节:

E1 << E2的结果是E1向左移动E2位; 空出的位用零填充。 如果E1具有无符号类型,则结果的值为E1 x 2E2,对表示结果类型的最大值加1取模。 如果E1具有已签名类型和非负值,并且E1 x 2E2可以表示在结果类型中,则该值是结果值;否则,行为未定义。

E1 >> E2的结果是E1向右移动E2位。 如果E1具有无符号类型或如果E1具有已签名类型和非负值,则结果的值为E1除以2E2的商的整数部分如果E1具有已签名类型和负值,则结果值是实现定义

因此,对于左移,如果a是有符号且为正,则定义良好。 如果a是有符号且为负,则未定义。

对于右移,如果a是有符号且为正,则定义良好。 如果a是有符号且为负,则实现定义。


你能给第二个问题解释一下吗? - phoxis
@Oil Charlesworth:太棒了。我应该保留一份标准的副本,它写得非常清晰。非常感谢您的回答。 - phoxis
2
@phoxis:公正地说,并不总是这么明确和清晰! - Oliver Charlesworth
1
标准的最清晰副本(转换为HTML):http://port70.net/~nsz/c/c99/n1256.html - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接