-2

I was shocked by the output of this... been coding in C for a few years now. Could someone explain a possible use case? Seems like it should be a compiler warning.

#include <stdio.h>

int chk(int var)
{
    return var++;
}

int main (void)
{
    int a = 1;

    a = chk(a);

    printf("var is: %d\n", a);

    return 0;

}

var is: 1

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Greasyjoe
  • 95
  • 1
  • 7
  • What value did you expect? Maybe pre-increment is the operator you wanted to use? – Adrian Maire Nov 28 '22 at 16:43
  • 5
    Why are you "shocked" and why do you think the compiler should issue a warning? – G.M. Nov 28 '22 at 16:43
  • 4
    I find this to be completely expected. On the other hand, if `++var` returned 1, I would be shocked. – General Grievance Nov 28 '22 at 16:45
  • Well, since return isn't on the order of operations, I assumed it was the very last thing to be executed – Greasyjoe Nov 28 '22 at 16:47
  • 2
    @G.M.: warnings "this operation has no effect" are absolutely welcome. –  Nov 28 '22 at 16:47
  • 1
    A `return` statement with an expression evaluates the expression to determine the function's return value, then terminates the function. If `var` initially has value `1`, then the result of evaluating `var++` is `1`. That evaluating that expression also produces a side effect on the value of `var` is irrelevant. – John Bollinger Nov 28 '22 at 16:48
  • 1
    _Could someone explain a possible use case?_ Not in this case, but it can be useful switching to `static`: `int chk(void){static int var = 1; return var++;}` returns the number of times the function has been called :) – David Ranieri Nov 28 '22 at 16:50
  • 1
    @David Ranieri;some hardware land voodoo – Greasyjoe Nov 28 '22 at 16:52
  • 1
    *Could someone explain a possible use case?* -- why does it need a use case? The observed behavior is a direct, natural consequence of the semantics of the language. There is no special rule involved to specify that result. – John Bollinger Nov 28 '22 at 16:53
  • @JohnBollinger, first time I have ever heard of an operator being referred to as a side effect, lol – Greasyjoe Nov 28 '22 at 16:54
  • *Seems like it should be a compiler warning* -- I could see a compiler warning about that, but that's between you and your compiler. C compilers are not responsible for warning about every detail of your code that they suspect might constitute a mistake. – John Bollinger Nov 28 '22 at 16:55
  • 2
    @Greasyjoe, I didn't say that an operator *was* a side effect, I said it *has* ("produces") a side effect. Evaluating an expression produces a value. Evaluating some expressions also produces changes in the program state, which the C language specification describes as "side effects". The change in the stored value of the operand of `++` is such an effect. So, by the way, is the change in the value of the left-hand operand of an `=` operator. – John Bollinger Nov 28 '22 at 16:58
  • @Greasyjoe It is executed last. And the answer is still 1. Hint: what number is `var++`? – user253751 Nov 28 '22 at 17:00
  • @Greasyjoe "some hardware land voodoo" - Perhaps `var` probably isn't local to `chk` and has lifetime beyond the function (your contrived example probably isn't equivalent). If that's the case it may make sense to "return the current value and then increment it". Maybe you can post the *actual* code where you saw this part. – P.P Nov 28 '22 at 17:01
  • 1
    Also, `return` is not an operator. See https://stackoverflow.com/a/2781278/. – General Grievance Nov 28 '22 at 17:01
  • This was basically, it. It was a state machine returning an index which was incremented each time it was called. – Greasyjoe Nov 28 '22 at 17:05
  • 1
    Does this answer your question? [What is the difference between ++i and i++?](https://stackoverflow.com/questions/24853/what-is-the-difference-between-i-and-i) – Nisse Engström Nov 28 '22 at 17:24
  • @JohnBollinger Perhaps a better way to say this might be that my grievance is that the definition of 'return' just says it returns the result of the experession. Is x++ not an expression?!? Somewhere I am missing the difference between { x++; return x} and { return x++; } – Greasyjoe Nov 28 '22 at 17:32
  • 2
    @Greasyjoe, absolutely `x++` is an expression. And it evaluates to the *initial* value of `x`, prior to the increment. That's the difference between `x++` and `++x` (both have the same side effect on the value of `x`, but the latter *evaluates to* 1 + the initial value of `x`). The behavior you describe reflects exactly that. – John Bollinger Nov 28 '22 at 19:01

2 Answers2

2

From the C Standard (6.5.2.4 Postfix increment and decrement operators)

2 The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it).

So the return statement in the function

int chk(int var)
{
    return var++;
}

returns the value of the parameter var before incrementing it. So acrually the postfix incrementing in this return statement does not have an effect and is equivalent to

return var;

That is the function returns the original value of the argument expression.

The function would be more meaningful if for example instead of the postfix increment operator it used the unary increment operator like

int chk(int var)
{
    return ++var;
}

In this case the function returns incremented value of the the value of the argument expression.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

In the computing model the C standard uses, return var++; has a main effect of return the value of var and a side effect of incrementing var. The value of var used for the return is the value prior to the increment.

Because var is a parameter of the function, incrementing it affects only the value of the parameter. It does not affect the argument a in the calling routine.

Seems like it should be a compiler warning.

Yes, this code performs a side effect that has no use, which could suggest a mistake by the author, so it is reasonable a compiler would warn about it.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312