在没有转换的情况下使用十六进制值时的未定义行为

Un-defined behavior when using hex values without Casting

这是我遇到过的最奇怪的问题。我正在编写一个国际象棋引擎,我有一个 return 等级掩码的功能。例如,考虑这个 64 位位板。

00000000
00000000
00000000
00000000
00000100
00000000
00000000
00000000

中间的1是一块

现在我的函数应该 return

00000000
00000000
00000000
00000000
11111111
00000000
00000000
00000000

很简单,就return一个等级掩码。这是我的代码

uint64_t get_rank_mask(int sq)
{
    return (0xFF<<(sq-(sq%8)));
}

这是函数 returns 当我通过 36 或正方形 e5

00000000
00000000
00000000
00000000
00000000
00000000
00000000
11111111

嗯,很奇怪。让我对代码做一点小改动。

uint64_t get_rank_mask(int sq)
{
    uint64_t mask = 0xFF;
    mask<<=(sq-(sq%8));
    return  mask;
}

这是现在的 return 值

00000000
00000000
00000000
11111111
00000000
00000000
00000000
00000000

神奇的是,这就是预期的结果。我什至不知道这两个代码示例之间的区别。谁能解释这种行为?

0xFF 是一个 int。假设 int 有 32 位,将这个值左移 32 将调用未定义的行为。

在第二个版本中,您将 0xFF 存储在无符号整数类型中。这可以移动任意数量的位,并且该操作定义明确。在你的情况下,你将它存储在一个 64 位的无符号整数中,因此向左移动 32 位会得到你想要的结果。