位移位和整数提升?

发布于 2024-09-14 23:48:38 字数 465 浏览 6 评论 0原文

通常,C 要求将二元运算符的操作数提升为较高级别操作数的类型。可以利用这一点来避免用详细的转换填充代码,例如:

if (x-48U<10) ...
y = x+0ULL << 40;

等等。

但是,我发现,至少对于 gcc,这种行为不适用于位移位。即,

int x = 1;
unsigned long long y = x << 32ULL;

我希望右侧操作数的类型会导致左侧操作数提升为unsigned long long,以便移位成功。但相反,gcc 会打印一条警告:

warning: left shift count >= width of type

gcc 是否已损坏,或者标准是否对位移位的类型提升规则做出了一些例外?

Normally, C requires that a binary operator's operands are promoted to the type of the higher-ranking operand. This can be exploited to avoid filling code with verbose casts, for example:

if (x-48U<10) ...
y = x+0ULL << 40;

etc.

However, I've found that, at least with gcc, this behavior does not work for bitshifts. I.e.

int x = 1;
unsigned long long y = x << 32ULL;

I would expect the type of the right-hand operand to cause the left-hand operand to be promoted to unsigned long long so that the shift succeeds. But instead, gcc prints a warning:

warning: left shift count >= width of type

Is gcc broken, or does the standard make some exception to the type promotion rules for bitshifts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小苏打饼 2024-09-21 23:48:38

所谓的通常的算术转换适用于许多二元运算符,但不是全部。例如,它们不适用于位移运算符、&&、||、逗号运算符和赋值运算符。这是移位运算符的规则:

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

The so-called usual arithmetic conversions apply to many binary operators, but not all of them. For example they do not apply to the bit shift operators, &&, ||, comma operator, and assignment operators. This is the rule for the bit shift operators:

6.5.7 ... 3 Semantics ...
The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

二智少女 2024-09-21 23:48:38

真正的麻烦在于,提升仅适用于您的平台定义为 int 的任何内容。正如其他一些答案所述,位移运算符会将左操作数提升为 int。但是,这里 int 被定义为 32 位值。整数转换不会提升为long long(64 位)。

The trouble really is that promotion only works up to whatever your platform defines as an int. As some other answers have stated, the bit-shift operator will promote the left operand to an int. However, here an int is defined as a 32-bit value. The integer conversion will not promote to a long long (64-bit).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文