3

Since b++ is post-increment,what happens to the increment of b if used as return b++ as in the following program?

#include<stdio.h>

int foo(int);

int main()
{
   int a=8;
   printf("%d",foo(a));
}

int foo(int a)
{
   static int  b=a*a;
    return b++;
}

Edit

#include<stdio.h>
int foo();

int main()
{
foo();
foo();
}

int foo()
{
    static int b=1;
    printf("%d\n",b);
    return b++;
}

Result

1

2

As I saw in my edit, why is b incremented at all?Isn't return supposed to exit that function immediately?Why is b incremented even after control returns to main()?Aren't all activities in the function supposed to end after return?

Thokchom
  • 1,602
  • 3
  • 17
  • 32
  • 1
    Note the keyword `static` on for `b`. This code does not compile with a C compiler. A C++ compiler does it, and the behaviour is "as you'd expect". – Mats Petersson May 12 '13 at 08:16

4 Answers4

5

Many C (sub-)expression have a value and a side effect.

The value of b++ is the value of b before evaluating the expression; its side effect is to increase the value in b by one.

So, the expression return b++; returns the previous value of b and updates b. When b is static the update stays around for the next function call; when b is a plain old local variable, the update is lost (a smart compiler will even not emit code to update the object).

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
pmg
  • 106,608
  • 13
  • 126
  • 198
4

Actually, this code doesn't compile, because b's initializer isn't a constant.

Since b is static, it's essentially a global variable, and it gets initialized before main, at which point a doesn't exist.

If on the other hand we compile this as C++, b is initialized the first time that foo is called - so gets the value 64. At the return, b++ is incremented and stored as 65 - but the return value is 64. So if you call foo again, it will return 65 (and b is 66).

Edit based on edited code:

So, the code essentially performs:

 int temp = b;
 b = b + 1;
 return temp; 

This is the way that C is define. The result of x++ is the previous value x, but the value of x is increment. Since static is essentially a global (but without a name, so you can't use it outside of that function), the value persists between calls to the function, and it is initialized before main is called.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Check my edited program.The first one didn't convey my point well.Why is `b` being incremented? – Thokchom May 12 '13 at 08:19
  • Aren't all activities in a function expected to end once `return` is encountered?Shouldn't `foo()` return `b` and pass control to `main()` instead of incrementing `b`? – Thokchom May 12 '13 at 08:21
  • No, `return b++;` will perform `b++`, then return the value given from that - which is the "old" value of `b`. – Mats Petersson May 12 '13 at 08:24
3

return b++; is equivalent to: int c = b; b = c + 1; return c;

To answer your new questions: - The function exits after return indeed, but before it returns, the expression b++ must be evaluated first. Evaluating such an expression will result in b being incremented. - All activities in the function "end" after return but b is declared as a static variable, in which case its value persists through subsequent executions of the function.

To make it easier for you to understand, a post increment is like the following function

int postincrement(int& x) {
    int y = x;
    x = x + 1;
    return y;
}

(Of course the compiler could optimize a b++ if it finds that incrementing b has no effect at all, but in this case it does have an effect (increment the static int b) so it can't be optimized out.)

javic
  • 823
  • 1
  • 6
  • 9
  • You are wrong.As per mvp's answer the increment never takes place because function returns control after `return b++`.The increment never happens. – Thokchom May 12 '13 at 08:09
  • 2
    b is a static variable so the increment will happen as it will maintain its state between calls to `foo`. – Steve May 12 '13 at 08:18
  • @steve Aren't all activities of the function supposed to stop after `return`?If there was a `printf()` after `return`, it would have been ignored for example.Why then the increment operation happens? – Thokchom May 12 '13 at 08:23
  • @Thokchom Please see my edits above. Also as you see, the increment does happen. – javic May 12 '13 at 08:24
  • @javic yes,it happens.But why?Isn't everything supposed to stop after `b` is returned? – Thokchom May 12 '13 at 08:25
  • As I explained - before returning, it needs to evaluate the expression `b++`. It's not `b` being returned. It's the result of that expression. And to get the result of that expression you have to evaluate that expression. Doing so has to increment `b` first. – javic May 12 '13 at 08:26
  • @Thokchom take a look at [sequence points](http://en.wikipedia.org/wiki/Sequence_point). – Steve May 12 '13 at 08:27
  • 2
    @Thokchom: If you were to `return printf("hi!\n");`, that would run too. The expression is evaluated, and any visible side effects it has will occur. (Any side effects the expression would have that can not be observed, the compiler is free to optimize away..but it's not *required* to.) – cHao May 12 '13 at 08:27
  • The question is tagged C and explaining it with a C++ function does not “make it easier to understand”. – Pascal Cuoq May 12 '13 at 09:11
  • Perhaps it *might* make it easier to understand, but it doesn't make it a particularly useful answer. This answer might mislead students into believing C has *pass-by-reference*, when it doesn't. @javic Perhaps you could explain the same concept with a preprocessor macro, instead. eg. `#define post_increment(x) ((x = x + 1) - 1)` – autistic May 12 '13 at 10:17
  • @Steve +1 to cHao on this point. Sequence points are trumped by the concept described in the C standard as *observable behavior*. – autistic May 12 '13 at 10:19
1

This post-increment is completely useless - because b has local scope, its incremented value is disposed after return. If your compiler is smart, it most likely to optimize it out.

mvp
  • 111,019
  • 13
  • 122
  • 148
  • The increment of b never happens,right?So isn't Javic's answer wrong? – Thokchom May 12 '13 at 08:11
  • It depends on how smart compiler is. Most likely it will not happen. However, if `b` was not `int`, but some object passed by reference, and `operator++` was redefined, then this *would* have some side effect. – mvp May 12 '13 at 08:13
  • You are BOTH wrong, the above code isn't compileable as C, since `a` is not a constant value. I'm writing up an answer that also explains the C++ solution, where the code IS valid. – Mats Petersson May 12 '13 at 08:14
  • @MatsPetersson Please check my edit that I'll be posting.It seems to agree with what you say and goes against the previous answers. – Thokchom May 12 '13 at 08:16