在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");
我不知道常量表达式是否可以使用上面的实现定义的操作的规则。
我知道,无论机器类型如何,负数的有符号左移都是未定义的。
是。C++11标准在[expr.shift]/3:中说
E1 >> E2
的值是E1
右移的E2
比特位置。如果E1
具有无符号类型,或者如果E1
具有有符号类型和非负数值,结果的值是E1/2^E2
如果E1具有带符号类型和负值结果值是实现定义的
在[expr.const]/2中,没有任何地方说这样的移位,或者通常具有实现定义值的表达式不是常量表达式。因此,您将获得一个常量表达式,该表达式具有实现定义的值。
这是合法的,因为它不会导致未定义的行为。
负值右移的行为是实现定义的。C和C++标准并不保证它是算术的或逻辑的;尽管据我所知,从来没有一个CPU不选择其中一个。