【问题标题】:returns true for ((unsigned int)0-1)>0((unsigned int)0-1)>0 返回真
【发布时间】:2017-12-25 00:58:19
【问题描述】:

我遇到了一些类似的 c++ 代码

if(((unsigned int)0-1)>0)
{
//do something
}

然后程序执行 if 块中的语句。出于好奇,我在 c 中尝试了同样的方法,结果也一样。我的理解是,如果 if 条件中的表达式返回布尔值 true,则 if 块中的语句将被执行。这意味着 ((unsigned int)0-1)>0 必须返回 true。为什么会这样?

【问题讨论】:

  • 当我找到((unsigned int)0-1) 时,我得到4294967295,所以看起来比较有效。
  • 如果条件是常数,那么作者显然不知道他们在做什么。没有进一步的上下文,这个问题无法回答。这可以很好地简化为 if(true),或者进一步展开为无条件语句。
  • 表达式(unsigned int)0 - 1unsigned int 类型。所以它总是>= 0,具体情况下是>0,因为!=0
  • 请使用更好的铸造技术。
  • (unsigned int)0 可以写成0U

标签: c++ if-statement


【解决方案1】:

对于(unsigned int)0-1operator- 的操作数是unsigned int 0int 1。那么结果的类型(即common type)将是unsigned int

否则,如果无符号操作数的转换等级大于或等于有符号操作数的转换等级,则将有符号操作数转换为无符号操作数的类型。

对于unsigned int,它不可能是0-1,但是

无符号整数运算总是执行模2n 其中 n 是该特定整数中的位数。例如。对于unsigned int,将UINT_MAX 加一得到0,从​0 减去一得到UINT_MAX

这意味着if(((unsigned int)0-1)>0) 等价于if(UINT_MAX>0),即true

【讨论】:

  • @downvoter 答案有错误吗?请告诉我,我会努力改进。
  • 我不是反对者。你已经编辑了你写的关于溢出的不正确之处。我认为这种迂腐的错误不值得投反对票。我也受到了随机投票的影响。事情发生了。
【解决方案2】:
if(((unsigned int)0-1)>0)

在普通算术中,0-1 为负一,不大于零。我们在这里处理的不是普通的算术。

C++(以及 C)优先规则表明强制转换优先于减法,因此 (unsigned int)0-1 等价于 ((unsigned int) 0)-1。换句话说,0 被视为unsigned int

接下来我们有一个unsigned int 减去一个签名的int。有关此类操作的 C++(和 C)规则是将有符号值视为无符号值。关于无符号运算的 C++(和 C)规则是执行模 2N 的计算,其中 N 是通用类型中的位数(对于 int,通常为 32,但没有保证)。 0-1 模 2N 是 2N-1,这是一个(大)正数。

引用标准,[basic.fundamental] 第 4 段,

无符号整数,声明为无符号,应遵守算术模 2 定律n 其中 n 是值表示中的位数那个特定大小的整数。46

和脚注:

46) 这意味着无符号算术不会溢出,因为不能由得到的无符号整数类型表示的结果以比得到的无符号整数类型可以表示的最大值大一的数字为模减少。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 2016-06-12
    • 2011-09-22
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 2010-11-18
    相关资源
    最近更新 更多