static_assert是否合法,签名右移具有两个补码行为?

时间:2014-10-20 20:24:27

标签: c++ c c++11 language-lawyer c11

在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");

我不知道关于是否可以使用上述实现定义的操作的常量表达式的规则。

我知道无论机器类型如何,相反的,带负号的左移,都是未定义的。

2 个答案:

答案 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没有选择其中一个。