【问题标题】:Is `x-- > 0 && array[x]` well-defined behavior in C++?`x--> 0 && array[x]` 在 C++ 中是明确定义的行为吗?
【发布时间】:2010-10-28 15:33:42
【问题描述】:

当我在左侧对布尔表达式进行后增量时,我可以在布尔表达式的两侧使用x吗?

有问题的行是:

 if(x-- > 0 && array[x]) { /* … use x … */ }

这是通过标准定义的吗? array[x] 会使用x 的新值还是旧值?

【问题讨论】:

  • 记住要保持你的代码干净,以供其他人阅读,即使定义良好,如果以后有人更改或添加到表达式中可能会引入问题。只是我的 2c
  • 即使它可以很好地定义,你也不应该使用这种类型的代码。你写的时候可能看懂了,但下一个人可能看不懂。
  • 这段代码毕竟还不错。我在 linux 内核中看到过更糟糕的代码:D
  • 请指定x的类型。如果 x 是整数,那么是的。如果它是一个类,取决于是否有人愚蠢到为该类定义 && 运算符(违反所有已知的编码约定)。
  • @knittl “毕竟还不错”-- 实在是太差了。我不会根据 linux 内核来判断我的代码。我们不想编写“还不错”的代码。我们希望编写简单明了、清晰明了的代码。

标签: c++ undefined-behavior post-increment


【解决方案1】:

视情况而定。

如果&& 是通常的短路逻辑运算符,那很好,因为有一个序列点。 array[x] 将使用新值。

如果&& 是用户(或库)定义的重载运算符,则不存在短路,也不能保证x-- 的评估和array[x] 的评估之间的序列点。鉴于您的代码,这看起来不太可能,但如果没有上下文,则无法确定。我认为,仔细定义array,这样安排是可能的。

这就是为什么重载operator&& 几乎总是一个坏主意。

顺便说一句,if ((x > 0) && array[--x]) 具有非常相似的效果(再次假设没有运算符重载恶作剧),并且在我看来更清晰。区别在于x 是否会递减到 0 以上,您可能依赖也可能不依赖。

【讨论】:

  • 你什么时候可以超载operator&&
  • 它是布尔运算符 && 并且没有重载
  • @Steve:即使 && 被重载,它仍然是定义的行为,不是吗?
  • @Zack:当然,既然 C++ 标准已经定稿,那之前我就不知道了。
  • @Armen:我认为不会,尽管在这种情况下我并不完全确定。我的想法是假设x 是整数类型,array 是某种类型 T 的数组,其中存在bool operator&&(bool, const T&) 重载。然后在x-- 的评估和array[x] 的评估之间没有序列点(因为没有一个是重载的),因此是未定义的行为。不过,我可能错过了一些使它定义的东西——我是 C++ 用户而不是 C++ 编译器编写者,所以如果我要犯错,我会尝试在假设某些东西是未定义的情况下犯错,除非另有证明。
【解决方案2】:

是的,它定义明确。 && 引入了一个序列点。

【讨论】:

  • 嗯,我感觉你或其他人正在使用 Twitter 之类的信息流来快速回复。当我第一次看到一个问题时,它通常已经回答了......?
  • @Alf P. Steinbach,每秒钟点击一次“问题”链接
  • @Alf:当我看到这个问题时,它没有答案,所以我回答了。诀窍是:至少每 10 秒刷新一次“新问题”页面。 ;-)
  • 那么,array[x] 使用旧值还是新值?
  • 嗯,我以为它会得到旧值......哦,好吧
猜你喜欢
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多