1

Is the increment in case of an expression involving x++ always made after the variable to be copy to a function ?

The call :

foo(x++, y);

The function :

int foo(int x, int y)
{
   return x*y;
}

Is that a undefined behavior for all compilers?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Melio500
  • 309
  • 3
  • 9
  • 7
    There's nothing undefined in the code you've shown as is. – StoryTeller - Unslander Monica Dec 18 '17 at 13:26
  • 1
    The suffix increment operation returns the *old* value. I.e. the value passed to the function will be the value before the increment. – Some programmer dude Dec 18 '17 at 13:26
  • 9
    And you can always replace the call `foo(x++, y);` with two lines: `foo(x, y); x++;` for clarity. Bonus points aren't awarded for stuffing as many operations into one line as you can. **Bugs** are awarded for doing that, though. – Andrew Henle Dec 18 '17 at 13:29
  • And for something like that ? sum += x*x++ ? My teacher said it Can be undefined – Melio500 Dec 18 '17 at 13:30
  • 5
    Not *can be*, but *is* undefined. But that's a different can of worms. – StoryTeller - Unslander Monica Dec 18 '17 at 13:32
  • 4
    For the last (`x * x++`) you should read http://stackoverflow.com/questions/949433/why-are-these-constructs-using-undefined-behavior. – Some programmer dude Dec 18 '17 at 13:32
  • 3
    As a point of order, whether or not something is undefined or not is not up to the compiler; the definition (i.e. the rules for the semantics) comes from the standard. – unwind Dec 18 '17 at 13:33
  • 3
    Just don't write crap code like that. Write `foo(x, y);` new line `x++;`. – Lundin Dec 18 '17 at 13:36
  • 1
    Rule of thumb: don't use this kind of operators if the operand appears more than one time in the expression. – 0___________ Dec 18 '17 at 13:36
  • 1
    @AndrewHenle: I would be cautious about saying “always.” `foo(x++, y);` is not equivalent to `foo(x, y); x++;` (for function calls generally, not the particular `foo` shown in this question). There is a sequence point after evaluation of the parameters and before the function call. So the increment of `x` occurs before the call in the former and after it in the latter. If the called function has access to `x` (by linkage or because `y` or something else points to it), it will observe a different value for `x`. – Eric Postpischil Dec 18 '17 at 14:11
  • @EricPostpischil I'd say that code that behaves that badly is even more bug-prone than cramming too much into one line. At least with too much into one line the confusion is presented all at once and not in the behavior of code not readily visible. – Andrew Henle Dec 18 '17 at 14:34
  • @AndrewHenle: Whether it is bug prone or not is irrelevant to the truth of the statement that one can always replace one with the other. – Eric Postpischil Dec 18 '17 at 14:36
  • in general, do not use 'side effects' in function calls. – user3629249 Dec 18 '17 at 15:02
  • @user3629249: That is going to make it difficult to print output, as printing is a side effect of calls like `printf` or `fputc`. – Eric Postpischil Dec 18 '17 at 18:56
  • @EricPostpischil, No, those functions have the purpose of printing to the terminal. So that is not a side effect. A side effect is like using pre- and post- increment/decrement on the parameters being passed to those functions. – user3629249 Dec 19 '17 at 12:37
  • @user3629249: These are formally defined as side effects in C 2011 5.1.2.3 2: “Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,…” – Eric Postpischil Dec 19 '17 at 12:41
  • @EricPostpischil, I limited my comment to the side effect that the OP was using. – user3629249 Dec 19 '17 at 14:42
  • @user3629249: Perhaps you did in your mind, but the words you wrote do not say there is such a limit. – Eric Postpischil Dec 19 '17 at 15:02

3 Answers3

10

Let's see the official descriptions here to get a deeper understanding.

For the postfix operator, quoting C11, chapter §6.5.2.3

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). [...] The value computation of the result is sequenced before the side effect of updating the stored value of the operand.

and, regarding the function call, chapter §6.5.2.3

There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.

So, as per above description, there's nothing problematic in your code as shown above.

The old value of x is passed and then, the value is increased.

However, please note the last part of the second quote, you need to maintain the sanity of the code. For example, you need to make sure, there's no change in value without having a sequence point in between. Something like

 foo(x++, x++, y);

will be a problem as, you're trying to changing the same variable (x) more than once.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

Consider the following program

#include <stdio.h>

int x;

void foo(int x1 )
{
    extern int x;

    printf( "x1 = %d\n", x1 );
    printf( "x = %d\n", x );
}

int main(void) 
{
    foo( x++ );

    return 0;
}

Its output is

x1 = 0
x = 1

Thus as it is seen the value of the expression x++ is the value of the operand before incrementing

x1 = 0

However the side effect was applied before the function gets the control

x = 1

The program is well-formed and there is no undefined behavior.

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

Whenever post increment is used, the original value of the variable will be sent to the function. And after that, the value of x will be incremented.

KulaDamian
  • 154
  • 2
  • 14