7

我在我的 gcc 上试过这个:

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

输出为0;但将其更改为

cout<<--(a--);

导致错误(需要作为减量操作数的左值)。有人可以启发我吗?

谢谢!

4

3 回答 3

12

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

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

于 2011-05-20T03:16:50.677 回答
8

predecrement --adecrements a,然后给你a自己。因此,您可以继续以任何您想要的方式对其进行修改,包括后减量。

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

将 predecrement 视为返回对 的引用a,而将 postdecrement 视为以常量值返回。

于 2011-05-20T03:16:44.243 回答
4
(--a)--

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

--(a--)

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

于 2011-05-20T03:19:14.897 回答