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

Is it legal to static_assert that signed shift right has two's-complement behavior?

本文关键字:补码 两个 是否 assert 右移 static      更新时间:2023-10-16

在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不选择其中一个。