【问题标题】:Should I use the ++ operator on temporary inline variables?我应该在临时内联变量上使用 ++ 运算符吗?
【发布时间】:2020-07-16 14:27:41
【问题描述】:

我想知道这个过早且不太重要的事情。我写过:

m_playerIndex = ++m_playerIndex % 2 // always either 0 or 1 (int)

对于我的国际象棋游戏,确保其他玩家在刚刚完成的移动之后会执行下一步。但是它不太可读,是吗?

最重要的是,它将一个变量增加 1,然后在适配变量上调用 2 的模块运算符,这意味着我有这个临时变量,我将其分配给 m_playerIndex 并立即将其替换为 % 的结果2.什么是最有效的?是选项2、1,还是根本没有区别? (我还没有检查这些东西的程序。)

1)

m_playerIndex = ++m_playerIndex % 2

2)

m_playerIndex = (m_playerIndex + 1) % 2

【问题讨论】:

  • 在 C 中,选项 1 是未定义的行为。 (从 C++17 开始,它在 C++ 中定义良好。但无论如何我都不会使用它,因为依赖于副作用顺序会给读者带来不必要的混淆。)
  • 选项 2 好得多,因为它比选项 1 更清楚地传达了意图。另一个查看代码并看到选项 1 的程序员会感到困惑,因为它看起来像一个错误或疏忽。选项 1 需要注释以通知后续程序员(很可能是您未来的自己)代码不是错误并故意增加 m_playerIndex,然后丢弃该工作。另外,请相信优化器(他们很棒),并且程序的易读性。
  • m_playerIndex = !m_playerIndex;m_playerIndex ^= 1; 如果你想混淆代码。
  • 不要问标记为 C 和 C++ 的问题,它们是不同的语言,需要不同的答案。

标签: c++ c performance


【解决方案1】:

表达式

m_playerIndex = (m_playerIndex + 1) % 2

清楚地向读者传达正在发生的事情。这里每一个可能的优化都是编译器的工作。

除此之外,为了您的好奇心,请查看https://godbolt.org/,您可以在其中查看和比较为您的代码创建的汇编指令。

【讨论】:

  • 感谢该网站!没听说过,以后会的。
【解决方案2】:

除了可读性或性能之外,您还有更大的问题 - 表达式的行为是未定义

您正试图通过++= 运算符多次更新m_playerIndex 而没有插入序列点。这不能保证达到您的预期。

为了使表达式定义明确,需要写成

m_playerIndex = (m_playerIndex + 1) % 2;

我不清楚为什么您认为除此之外还需要增加变量,因为结果只会是 01

【讨论】:

  • 那是为了缩短 if 语句(也许我应该测试代码是否也更快)。我认为最明确的方法是if (m_p == 0) {m_p = 1;} else {m_p = 0;}(忽略位操作)
  • @BlayerBond:对我来说不太清楚,我们必须检查每个分支以了解其意图。 m_p = (m_p == 0) ? 1 : 0; IMO 会更好。但cond ? 1 : 0 主要等同于cond,所以m_p = m_p == 0; 甚至m_p = !m_p; 传达的IMO 意图较少。
  • 确实更清楚,但我宁愿不要像布尔值那样对待整数,即使它们只能是 0 或 1,也不是说 !-operator 仅用于布尔值,但我仅将其用于对我有意义的事情。
  • @rici,喜欢它,虽然它比我在这里看到的任何东西都更能隐藏意图:)
  • @ypnos 我想这取决于读者。这对我来说似乎很清楚:-) 因为x = <constant> - x 显然是两种状态。 (如果所需的两个状态是 1 和 -1,您不会抱怨 x = -x,对吗?)有些人可能更喜欢 x = x ^ 1,因为他们很早就知道 XOR 是两种状态。但减法对我来说更自然。
猜你喜欢
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 2010-12-11
相关资源
最近更新 更多