面试问题中这个位操作代码有什么问题?

时间:2010-11-23 01:36:13

标签: c++ c bit-manipulation integer-promotion

我正在查看此页面:http://www.devbistro.com/tech-interview-questions/Cplusplus.jsp,并且不明白这个问题:

  

以下代码可能有什么问题?

long value;
//some stuff
value &= 0xFFFF;
     

注意:向候选人提供有关他们正在开发的基础平台的提示。如果该人仍然没有发现代码有任何问题,他们就没有C ++经验。

有人可以详细说明吗?

谢谢!

7 个答案:

答案 0 :(得分:41)

此处的几个答案指出,如果int的宽度为16位,则0xFFFF为负数。这不是真的。 0xFFFF永远不会消极。

十六进制文字由以下第一种类型表示,其大小足以包含它:intunsigned intlongunsigned long

如果int的宽度为16位,则0xFFFF大于int可表示的最大值。因此,0xFFFF的类型为unsigned int,保证其足够大以代表0xFFFF

当执行通常的算术转换以评估&时,unsigned int将转换为long。 16位unsigned intlong的转换是明确定义的,因为16位unsigned int可表示的每个值也可由32位long表示。

无需签名扩展名,因为初始类型未签名,使用0xFFFF的结果与使用0xFFFFL的结果相同。

或者,如果int宽于16位,则0xFFFF的类型为int。这是一个签名但积极的号码。在这种情况下,两个操作数都已签名,long具有更高的转换排名,因此通过常规算术转换将int再次提升为long


正如其他人所说,你应该避免对有符号操作数执行按位运算,因为数字结果取决于符号的表示方式。

除此之外,这段代码没有什么特别的错误。我认为这是一种风格问题value在声明时未被初始化,但这可能是一个挑选级别的注释,并取决于省略的//some stuff部分的内容。

最好使用固定宽度的整数类型(如uint32_t)而不是long来提高可移植性,但实际上这也取决于您编写的代码以及您的基本假设是

答案 1 :(得分:3)

我认为根据长度的大小,0xffff文字(-1)可以被提升为更大的大小并且是有符号值,它将被符号扩展,可能变为0xffffffff(仍为-1)。

答案 2 :(得分:2)

我会假设它是因为长期没有预定义的大小,除了它必须至少与前面的大小(int)一样大。因此,根据大小,您可能会将值截断为位子集(如果长度超过32位)或溢出(如果小于32位)。

是的,多头(根据规格,并感谢评论中的提醒)必须能够至少保持-2147483647到2147483647(LONG_MIN和LONG_MAX)。

答案 3 :(得分:1)

因为在执行之前没有初始化一个值,所以我认为行为是未定义的,值可以是任何值。

答案 4 :(得分:0)

long type size是特定于平台/编译器的。

你能说的是:

  1. 签名。
  2. 我们无法知道值& = 0xFFFF的结果;因为它可以是例如值& = 0x0000FFFF;并且不会做出预期的事。

答案 5 :(得分:0)

虽然有人可能会争辩说,因为它不是缓冲区溢出或其他可能被利用的错误,所以它是样式的东西而不是错误,我99%对答案有信心问题撰稿人正在寻找的是value在被分配之前进行操作。这个值将是任意垃圾,这不太可能是意思,所以它“可能是错误的”。

答案 6 :(得分:-1)

使用MSVC我认为该语句将执行最有可能的意图 - 即:清除所有但最不重要的16位值,但我遇到了其他平台,它们将字面值0xffff解释为等效于(short) -1,然后sign extend转换为long,在这种情况下语句“value& = 0xFFFF”将不起作用。 “value& = 0x0FFFF”更明确,更健壮。