当我在布尔表达式的左侧后置增量时,可以同时在两侧使用x
吗?
问题所在的行是:
if(x-- > 0 && array[x]) { /* … use x … */ }
这是否是通过标准定义的?array[x]
会使用新值还是旧值?
当我在布尔表达式的左侧后置增量时,可以同时在两侧使用x
吗?
问题所在的行是:
if(x-- > 0 && array[x]) { /* … use x … */ }
这是否是通过标准定义的?array[x]
会使用新值还是旧值?
这要看情况而定。
如果&&
是通常的短路逻辑运算符,那么没问题,因为有一个顺序点。此时array[x]
将使用新值。
如果&&
是用户(或库)定义的重载运算符,则没有短路,并且在评估x--
和评估array[x]
之间没有顺序点的保证。鉴于您提供的代码,这看起来不太可能发生,但是没有上下文很难确定。我认为,通过仔细定义array
,可以安排成这样。
这就是为什么几乎总是不建议重载operator&&
的原因。
顺便说一下,if ((x > 0) && array[--x])
具有非常类似的效果(再次假设没有运算符重载诡计),并且在我看来更加清晰明了。区别在于是否会将x
递减到0以下,取决于你是否依赖它。
x
是整数类型,而array
是某种类型T的数组,其中存在一个bool operator&&(bool,const T&)
重载。那么在x--
和array[x]
的评估之间没有序列点(因为它们都没有被重载),因此会导致未定义的行为。虽然我可能错过了一些使其定义的东西,但我是C++用户而不是C++编译器编写者,所以如果我要犯错,我会尝试从假定某些东西是未定义的方面出发。 - Steve Jessop是的,这是定义良好的。 &&
介绍了一个序列点。
array[x]
使用旧值还是新值? - knittl&&
引入了一个序列点。无论如何,我觉得那段代码相当糟糕。使用两个if语句更清晰、更容易调试。调试比起一开始编写代码来说要困难两倍。因此,如果你尽可能聪明地编写代码,那么根据定义,你并不足够聪明来进行调试。这一点尤其适用于其他人需要调试你的代码的情况,因为并非所有人都具有相同的知识和经验水平。 - BЈовић