【问题标题】:Precedence of increment and decrement opreators in C++C++中递增和递减运算符的优先级
【发布时间】:2011-08-29 08:27:30
【问题描述】:

我在我的 gcc 上试过这个:

int a=1;
cout<<(--a)--;

输出为0;但改成

cout<<--(a--);

导致错误(需要左值作为减量操作数)。有人能告诉我这个吗?

谢谢!

【问题讨论】:

  • 不要只告诉我们你有错误,告诉我们那个错误是什么!(如果你有,我会投赞成票,但如果没有,它可以这不是一个好问题。)
  • 现在我看了一下,它说“需要左值作为减量操作数”。
  • @Fred Nurk 感谢您的评论。已编辑:)
  • 总是阅读错误,如果您不理解,请查阅。通过将该错误文本复制并粘贴到 Google 返回的第一页有您问题的答案。
  • 这是关于 SO 的最常见问题之一。从stackoverflow.com/questions/1525187/… 开始,查看“链接”侧边栏,您会看到很多很好的答案。

标签: c++ increment decrement


【解决方案1】:
(--a)--

这是未定义的行为,因为您在没有中间序列点的情况下修改了同一个对象两次。当您调用 UB 时,编译器不需要报告——它无法在许多情况下甚至检测到 UB。但是,如果您打开正确的警告(并且您应该查看您提供的警告),它有时可能会这样做。

--(a--)

前缀减量需要一个左值,但后缀减量返回一个右值。这是一个错误,与未定义的行为不同,编译器需要报告。

【讨论】:

    【解决方案2】:

    ++ 的两个版本都需要左值作为参数,但前缀版本返回一个左值作为参数,而后缀版本返回一个右值。

    无论哪种方式,您都不能在序列点之间修改同一个对象两次,因此您的“工作”示例会调用 undefind 行为。输出可以是编译器想要做的任何事情。如果您只是出于好奇而询问,那很好,但如果这与您的实际代码相关,您可能做错了什么。

    【讨论】:

    • 挂个勾,如果前缀增量不算作序列点,为什么它返回一个左值? (注意它不在 C 中)
    • @Random832 - 因为在 C 中只定义了大约七个序列点。赋值运算符也不是序列点。如果你问“为什么”,它可能会是“因为这需要更多的开销并且可能会使代码变慢。”
    • 不过,它们都没有在 C 中返回左值。你不能分配的左值有什么意义?
    • @Random832 - 是的。 (a = b) = c 在 G++ 中编译。 (普通的 GCC 实际上会发出一个我不知道如何禁用的错误,这是一件好事,但它在语法上仍然有效。)
    【解决方案3】:

    先递减 --a 递减 a,然后返回 a 本身。因此,您可以继续以任何您想要的方式对其进行修改,包括后减量。

    postdecrement a-- 递减 a 但在递减之前返回 a 的值。它本质上是给你一份a 的副本。但是你不能再减少这个副本。它不是左值,所以没有什么可以减少的。这就是为什么它是一个错误。

    将预减量视为返回对a 的引用,将后减量视为以常量值返回。

    【讨论】:

    • "因此您可以继续以任何您想要的方式对其进行修改,包括后减量。"错误,您可以,但这样做是未定义的行为。
    • @Chris,是的,但是在 C++0x 中可以这样做
    • 当 C++0x 出现时,无论是否是 UB,在代码中写 ++++++++x 仍然是个坏主意。
    猜你喜欢
    • 1970-01-01
    • 2013-06-18
    • 2017-07-18
    • 2015-10-03
    • 2019-12-06
    • 2013-06-18
    • 2011-02-16
    • 2014-03-21
    相关资源
    最近更新 更多