在C11,C ++ 11和C ++ 14中执行以下操作是否合法?
static_assert(((-4) >> 1) == -2, "my code assumes sign-extending right shift");
或C等价物:
_Static_assert(((-4) >> 1) == -2, "my code assumes sign-extending right shift");
我不知道关于是否可以使用上述实现定义的操作的常量表达式的规则。
我知道无论机器类型如何,相反的,带负号的左移,都是未定义的。
答案 0 :(得分:6)
是。 C ++ 11标准在[expr.shift] / 3中说明:
E1 >> E2
的值为E1
右移E2
位位置。如果E1
具有无符号类型,或者E1
具有签名类型且非负数 值,结果的值是商的整数部分E1/2^E2
。 如果E1有签名类型和负值,则 结果值是实现定义的。
并且在[expr.const] / 2中没有任何地方可以说这样的移位,或者通常具有实现定义值的表达式,不是常量表达式。 因此,您将获得具有实现定义值的常量表达式。
答案 1 :(得分:3)
这是合法的,因为它不会导致不确定的行为。
负值右移的行为是实现定义的。 C和C ++标准不保证它是算术的还是逻辑的;虽然据我所知,从来没有一个CPU没有选择其中一个。