0

I think it is a very simple question... I've some code like this:

//head is somewhere initialized with 0 (int head=0;)
char testclass::read() {
    return data[head];
    ++head;
}

When I try to run it I create a loop. Changing it to:

char testclass::read() {
    ++head;
    return data[head];
}

runs without a problem, except that head is incremented to fast. So what's the problem?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
user2777080
  • 63
  • 1
  • 3
  • 1
    `return` returns from the function. Anything after that won't happen. – chris Sep 15 '13 at 16:38
  • 3
    What do you mean head is incremented too fast? It increments once each time you call the function. – Benjamin Lindley Sep 15 '13 at 16:40
  • 1
    What do you mean when you try to run it you create a loop? – SwiftMango Sep 15 '13 at 16:41
  • I wonder why the question was downvoted. The fact that StackOverflow is an English website does not mean all its users speak English as a mother language. And "to fast" was clearly understandable from the context: too early. Anyway I upvoted it to compensate. :-) – SzG Sep 15 '13 at 17:05

4 Answers4

2

Try this.

return data[head++];

In your first solution ++head after the return is dead code. Never runs, it's probably thrown away already in compile time. In your second solution, head's been already incremented by the time you return. Too early.

The post-increment ++ operator increments the value sometimes after the evaluation of the head++ expression and before the semicolon. But the exact time is undefined and compiler-dependent. Therefore never use multiple x++ expressions within the same statement.

SzG
  • 12,333
  • 4
  • 28
  • 41
  • 3
    Can you provide an explanation to this answer, btw I was not the downvoter. – Shafik Yaghmour Sep 15 '13 at 16:40
  • 1
    The description of post-inc, while suitable for the OP, is not accurate. The term `head++` as an eval-expression essentially means take the current value of head, remember it, increment head, then use the original value as the eval result. In other words, head *is* incremented before `data` is subscripted, but it isn't `head`s value that is being used for the subscript. it is the value of head *prior* to the increment. This is trivially demonstrable with a function call and a global variable used as the increment op. – WhozCraig Sep 15 '13 at 16:56
  • 1
    Post-increment does not increment "after the evaluation of `head++`". This is probably one of the most widespread and dangerous misconceptions about pre- and post- sequencing. The key point about the `head++` is that it evaluates to the old, original value of `head`. That's all we know and that's all we need to know. At what point the actual increment happens - before, after, somewhere in the middle - no one knows and it does not really matter. – AnT stands with Russia Sep 15 '13 at 17:19
  • There must be some misunderstanding here, as we both state the same thing. :-) – SzG Sep 15 '13 at 17:22
2

You can do:

return data[head++];

because the behavior of returning a post-incremented variable is defined. The

int foo() { return x++; }

is equivalent to:

int foo()
{
  int temp = x;
  ++x;
  return temp;
}

in your example:

return data[head++];

would be the same as:

{
  int temp = head;
  ++head;
  return data[temp];
}
4pie0
  • 29,204
  • 9
  • 82
  • 118
  • 1
    +1 for the behavioral example of post-inc. You'd probably not be surprised how many *professors* aren't aware it works that way. – WhozCraig Sep 15 '13 at 16:57
1

I think what you want is this:

char testclass::read() {
    char result = data[head];
    ++head;
    return result;
}

but as SzG said, this can be abbreviated to return data[head++];

Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
0

First, your need to know What is the difference between ++i and i++?.

In your case, you want to:

  1. read your data at head
  2. move your head
  3. return the value read in 1.

So, in code it looks like that:

char testclass::read() {
    char result = data[head];     // 1
    head += 1;                    // 2
    return result;                // 3
}

Now, you can use ++head or head++ instead of head += 1 here. It won't change the behaviour of your function because the result of this statement is not used (i.e. you can do x = y += 1; but probably don't want to.)

If you want, you can make write this function in one line, but will lose in readability (it's often better to have only one statement by line, it's less error-prone this way):

return data[head++];

This works because head++ increment the variable but return its "old" value.

But don't think it's faster that the three-line code: your compiler is clever enough to optimize that and will most probably generate the same assembly code for both implementation.


Regarding your first version of the function, don't forget that code after a return statement are not executed. (See for example this SO Execution of code in a function after the return statement has been accessed in c++)

Community
  • 1
  • 1
Hiura
  • 3,500
  • 2
  • 20
  • 39