【问题标题】:c++ safe counting backwards to zero for "auto" integral type对于“自动”整数类型,C++ 安全倒数到零
【发布时间】:2017-08-14 21:38:34
【问题描述】:

expression 成为整数类型,在编译时已知,可能有符号,也可能无符号。按照这种方式倒数到零是否安全(假设表达式的实际值为非负数)?

for(auto i = expression; i!= static_cast<decltype(i)>(-1); --i) {
  //something
}

【问题讨论】:

  • 为什么在 for 循环中使用 auto?获得未定义行为的机会非常高。
  • 那里不需要那个演员表,除非你只是想抑制编译器警告。

标签: c++


【解决方案1】:

这是安全的。但在我看来,它很难阅读,安全性/正确性也不一定是直观的(毕竟,你为什么还要问别的)。我建议:

for(auto i = expression; i-- > 0;)

(也称为“转到”运算符,格式不同时:i --&gt; 0)。


编辑:正如所指出的,这与所讨论的循环的行为并不完全相同。 expression 的初始值不会被迭代,而是循环将从 expression - 1 开始(因此会有精确的 expression 迭代次数)。

【讨论】:

  • 应该为i = expression 完成循环,所以你应该写auto i = expression+1。就个人而言,我觉得这种方式可读性较差,但当然这是一个测试问题。无论如何,感谢您确认我的变体是安全的。
  • @DmitryJ 哦,您对初始迭代是正确的。好点。
  • 不确定这个 +1 部分。如果表达式计算为 std::numeric_limits::max 怎么办?
  • @Tomek 确实,这种方法无法处理这种情况。这是否是一个问题取决于上下文。使用它的最理想情况是,如果您只想要 expression 迭代次数,而不是从 expression 开始的数字(这不完全是所讨论的循环的行为)。
【解决方案2】:

这实际上可能非常危险,因为您允许 expression 可能为负数。如果发生这种情况,您的代码将从expression 的值开始计数到负无穷大,这是未定义的行为(没有人知道i 达到整数限制后会发生什么)。你基本上有一个没有 break 子句的 for 循环。

【讨论】:

  • 行为将是未定义的,而不是无限循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 2016-05-17
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
相关资源
最近更新 更多