11

Can I use x on both sides of a boolean expression when I post-increment it on the left side?

The line in question is:

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

Is that defined through the standard? Will array[x] use the new value of x or the old one?

5
  • 7
    remember to keep your code clean for others to read, even if is well defined it may introduce an issue if somebody later changes or adds to the expression. Just my 2c
    – AndersK
    Commented Oct 28, 2010 at 15:37
  • 6
    Even if it may be well defined, you should not use such kind code. You may understand it as you write it, but the next peson may not.
    – codymanix
    Commented Oct 28, 2010 at 15:39
  • this code is not too bad after all. i've seen worse code in the linux kernel :D
    – knittl
    Commented Oct 28, 2010 at 15:48
  • Please specify the type of x. If x is an integer then yes. If it is a class depends on if somebody was stupid enough to define the && operator for the class (against every coding convention known). Commented Oct 28, 2010 at 18:05
  • @knittl "not too bad after all"-- Poor praise indeed. I wouldn't judge my code against the linux kernel. We don't want to write code that is "not too bad". We want to write code that is simple and obvious, clear and clean.
    – Rob K
    Commented Jan 3, 2017 at 20:54

2 Answers 2

12

It depends.

If && is the usual short-circuiting logical operator, then it's fine because there's a sequence point. array[x] will use the new value.

If && is a user (or library) defined overloaded operator, then there is no short-circuit, and also no guarantee of a sequence point between the evaluation of x-- and the evaluation of array[x]. This looks unlikely given your code, but without context it is not possible to say for sure. I think it's possible, with careful definition of array, to arrange it that way.

This is why it's almost always a bad idea to overload operator&&.

By the way, if ((x > 0) && array[--x]) has a very similar effect (again, assuming no operator overloading shenanigans), and in my opinion is clearer. The difference is whether or not x gets decremented past 0, which you may or may not be relying on.

7
  • Since when can you overload operator&& at all?
    – zwol
    Commented Oct 28, 2010 at 15:45
  • it's the boolean operator && and it's not overloaded
    – knittl
    Commented Oct 28, 2010 at 15:45
  • @Steve: Even if && were overloaded it would still be defined behavior, no? Commented Oct 28, 2010 at 15:46
  • @Zack: certainly since the C++ standard was finalized, I don't know about before that. Commented Oct 28, 2010 at 15:49
  • @Armen: I think not, although I'm not entirely sure in this case. My thinking is that suppose x is an integer type, and array is an array of some type T for which a bool operator&&(bool, const T&) overload exists. Then there's no sequence point between the evaluation of x-- and the evaluation of array[x] (because none of that is overloaded), hence undefined behavior. I may have missed something which makes it defined, though - I'm a C++ user rather than a C++ compiler-writer, so if I'm going to err I try to err on the side of assuming something is undefined until proven otherwise. Commented Oct 28, 2010 at 15:50
11

Yes, it is well defined. && introduces a sequence point.

8
  • 1
    Huh, I have the feeling that you or others are using some feed like Twitter in order to answer so darned fast. When I first see a question it's generally already answered... ? Commented Oct 28, 2010 at 15:37
  • @Alf P. Steinbach, click the "questions" link once in a second
    – Harmen
    Commented Oct 28, 2010 at 15:38
  • @Alf: When I saw this question it was unanswered and so I answered it. The trick is : Refresh the "New questions" page at least once in 10 seconds. ;-) Commented Oct 28, 2010 at 15:40
  • 1
    so, array[x] uses the old or the new value?
    – knittl
    Commented Oct 28, 2010 at 15:49
  • hmm I thought it would get the old value... oh well Commented Oct 28, 2010 at 18:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.