2

If I have code like:

int pop()
{
    return stack[--stp];
}

I know that it is doing two things. It is returning the value contained in the one-dimensional array 'stack' in element 'stp'. It is also decrementing 'stp'.

But which order does this happen in?

Does it return the value of element stp, then decrement stp?

Or does it decrement stp, then return the value of the element now referred to by the decremented stp?

If the code is:

int top()
{
    return stack[stp-1];
}

Does it work any differently?

My apologies, I know this is very common coding style - I still have some trouble making sense of concise, uncommented code - even basics like this. Sorry.

Ahmad Farid
  • 14,398
  • 45
  • 96
  • 136
Eilidh
  • 1,354
  • 5
  • 21
  • 43
  • if the syntax isn't immediately clear to you, I would suggest not using it since it'll make reading your own code that much harder. – Matthieu M. Nov 19 '10 at 15:19

8 Answers8

7

It will decrement stp, and then return the value from the array at the location of the new stp value.

--stp is a "prefix decrement", and it is defined to decrement the argument (stp), and then return the new value. It has a counterpart called the "postfix decrement", stp--, which decrements stp and then returns the old value - so stack[stp--] will give you the value the current stp offset, but still decrement stp.

Finally, your version with stack[stp-1] will return the value from the same place as stack[--stp], but stp itself will be unchanged.

Chowlett
  • 45,935
  • 20
  • 116
  • 150
  • 2
    "and then" implies an ordering that isn't guaranteed. Then value of `--stp` is the decremented value and the side-effect will store that value back to `stp` but the side-effect doesn't have to be completed before the value is used in the expression, it only has to be completed by the next sequence point. (In this case, there's no observable difference but in general there may be.) – CB Bailey Nov 19 '10 at 15:06
  • Valid point. Is it worth editing the answer to read "...defined to return the new, decrement value while storing that in `stp`", or is the distinction minor enough to leave in comments? – Chowlett Nov 19 '10 at 16:17
2

Simple answer: decrement first, then the array access.

More complicated answer: this code uses the prefix decrement operator, which is pre-decrement. This means that the the operator's result value, is the value after the decrement is performed.

Contrast this with the post-decrement operator. return stack[stp--]; would also decrement stp, but the index used would be the initial value.

For complex technical reasons which allow compilers maximum freedom to optimize, it isn't defined exactly when stp is modified. But what is certainly defined is that the value used as the array index is the value that stp would have, once decremented.

Your code for top() doesn't modify stp at all, but it's the same in the sense that the value it uses as the array index, is one less than the initial value of stp. So if you call top(), the value you get back is the same value you'll get next time you call pop().

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • Is the bit in square brackets always done first, before the return? – Eilidh Nov 19 '10 at 15:00
  • @SG3: its value is calculated before the return, because it's needed to calculate the return value. Side-effects are a bit complicated, and the modification of `stp` is a side-effect, but `stp` itself isn't used in the array lookup, only the value of the expression in the []. Basically, the C++ standard doesn't say what it means to "do" an expression - it says what the result is, and it says what the side-effects are, and it says that the side effects happen after the "previous" sequence point, and before the "next" sequence point. – Steve Jessop Nov 19 '10 at 15:03
  • There's lots more info here: http://stackoverflow.com/questions/4176328/faq-undefined-behavior-and-sequence-points. It isn't needed for such a simple case, only to explain why a simple rule such as "`stp` is modified first" is not always correct. – Steve Jessop Nov 19 '10 at 15:09
1
  • --stp = Pre-decrement. stp is decremented BEFORE it's used.
  • stp-- = Post-decrement. stp is decremented AFTER it's used.
Roddy
  • 66,617
  • 42
  • 165
  • 277
1

There are two versions of the decrement (and also increment) operator, like --i and i--. If you think of them as functions (which they are), the code would be (this assumes you know what operator overloading is, otherwise, see HERE).

// --i
int operator--() {
    *this = *this - 1;
    return *this;
}

// i--
int operator--(int i) {
   int retVal = *this;
    *this = *this - 1;
    return retVal;
}

So, point being:

i-- returns the value BEFORE the decrement

--i returns the value AFTER the decrement


As for

int top() { return stack[stp-1]; }

This will return the index at one less than stp. However, because you haven't assigned a new value to stp, stp will be the same value after its done (which is probably not what you want).

Roadrunner-EX
  • 824
  • 11
  • 23
1

return expression; means "evaluate the expression and return the result to the caller". You cannot have anything else happen after a function has returned to its caller. It is impossible to first return to the caller and then cause some side-effect.

Even if you had written return i++; or something, it would still have meant "evalute the expression i++ and then return the result to the caller". It just so happens that the result of i++ is the value that i had before it was incremented, but still, i was incremented. Simply think of i++ as (++i - 1).

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
0

There are two types of increment/decrement operations: prefix and postfix. When use prefix operators, the the operation is executed firstly, then the access happens. In postfix the first is the access, the second is the operation.

So, in:

--stp;

stp will be decremented and then accessed.

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
0

if the code is return stack[stp-1], it works differently, namely that stp is not modified.

Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
0

The instruction return stack[--stp]; works int he following way:

  • The expression to be returned is evaluated
  • The result of the evaluation is returned

Therefore, the value of stp is decremented. As for your other other question, that is if

return stack[--stp];

is equivalent to

return stack[stp-1];

that depends of the nature of stp. If it is an automatic variable, the change of stp has no effect.

Luca Martini
  • 1,434
  • 1
  • 15
  • 35