【问题标题】:Short-circuiting of non-booleans非布尔值的短路
【发布时间】:2015-06-03 13:22:25
【问题描述】:

缩短这种三元运算符的用法是否安全:

process_ptr(ptr ? ptr : default_ptr);

短路:

process_ptr(ptr || default_ptr);

在 C 和 C++ 中?换句话说,我们是否保证从表达式中得到 either ptr default_ptr,或者是否允许表达式导致任意的 "逻辑真”值,如果表达式逻辑真?

这是您在 Perl 代码中看到的那种代码,但我很少在 C/C++ 中看到它,这是我提出问题的最初基础。

【问题讨论】:

  • 我几乎可以肯定ptr || default_ptr 将评估为10
  • 条件表达式将返回一个值,但逻辑表达式将始终返回 0 或 1。
  • 您是否考虑过检查结果以查看您关于它可能安全的假设是否有效? (你现在应该已经有了答案。)
  • 只是好奇:GCC 具有支持ptr ?: default_ptr 以获得此问题中寻求的行为的非标准行为...docs here。如果您实际使用它,您可能需要调整警告。

标签: c++ c


【解决方案1】:

第二个表达式将计算为10

引用 C11 标准草案:

6.5.14 逻辑或运算符

  1. || 运算符在其任一操作数比较不等于 0 时应产生 1;否则,它产生 0。结果的类型为 int

所以这两个表达式非常不同,因为其中一个产生一个指针,另一个产生一个整数。

编辑

其中一个cmets声称这个答案只对c有效,@Lightness Races in Orbit是对的。

也有只对 c++1 正确的答案,尽管与它们的唯一区别是 c++ 的类型为 bool,然后它将此表达式计算为 bool 而不是 @987654332 @。但是apparently there is an important issue with overloading || operator in c++,它可以防止对重载它的对象应用进行简短引用。

所以对于 c++ 来说,还有更多的事情需要考虑,但是由于这个问题是用两种语言标记的,所以至少有必要提到它们的区别。

当短路应用时,该规则仍然适用,即表达式的评估结果是 10 对于 c 和 truefalse 对于 c++。


1 喜欢这些答案:12

【讨论】:

  • 对答案的编辑没有意义,我认为因为您错误地引用了@LightnessRacesinOrbit 声称答案仅在 C++ 中有效(这使得第二段看起来令人困惑和矛盾)。此外,我没有看到指向 YouTube 火焰诱饵的链接声称 C 和 C++ 应该是一种语言的意义。
  • @jadarnel27 视频的链接,只是要注意,即使c和c++不是同一种语言,c++也尽量和c一样,因为创作者的初衷是使其成为一种语言。
  • @jadarnel27:这也是误导/错误的,因为它表明 C 和 C++ 之间的唯一区别是表达式的类型,而实际上,短路——表面上是这个问题的重点——仅适用于内置布尔运算符。 Once you overload them, a C++ feature, that goes away。否则我可能不会打扰评论。因此,答案仍然有点错误。也就是说,尽管有标题,但很难看出短路真正在哪里适合这个问题。
  • @LightnessRacesinOrbit 我明白你的意思,你说得对,这也是我不喜欢 c++ 的原因之一,它太复杂了。
  • @iharob: 真的很糟糕 :)
【解决方案2】:

关于 Perl 风格,通常是类型

do_someting || die("didn't work")

这也适用于 C++。

function_returning_bool(some) || std::cout << "Error!" << std::endl;

这是因为|| 是一个逻辑或运算符,如果返回值为真,在这种情况下会导致短路。

但是用它代替三元运算符是不可能的。

std::cout << ("asd" || "dsa");

这将导致1 被输出。

【讨论】:

  • Nitpick,如果来自function_returning_bool() 的返回值是一个具有覆盖operator||() 方法的类,则不会发生短路......
  • @AndreKostur 谢谢,忘记了。我总是喜欢吹毛求疵:)
  • 显然,condition() || exec_on_false() 是否是好风格是一个品味问题。我宁愿说不是:因为结果是布尔值,你几乎只能将它用于仅具有副作用的功能,而对于这些你不妨使用if,这更清楚。
【解决方案3】:

没有。结果类型为int(或C++ 中的bool),将是10(C++ 中的truefalse)。

【讨论】:

    【解决方案4】:

    operator|| 指针返回一个bool,所以如果ptrdefault_ptr 不为空,ptr || default_ptr 将计算为true

    【讨论】:

      猜你喜欢
      • 2015-04-10
      • 2011-08-04
      • 2019-08-27
      • 1970-01-01
      • 2011-12-26
      • 2014-03-23
      • 2012-10-25
      • 2012-06-25
      • 1970-01-01
      相关资源
      最近更新 更多