4

I am not getting that how the following code is executing and output is 1 2 3 4 5 . Specially that return statement in reverse function with (i++, i).

#include <stdio.h>

void reverse(int i);

int main()
{
   reverse(1);
}

void reverse(int i)
{
   if (i > 5)
     return ;
   printf("%d ", i);
   return reverse((i++, i));
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    Welcome to SO. This is a good time to learn how to use a debugger. Run your program in GDB and you can follow the execution path to see why you get that output. You might also want to read a few basics about recursion. – Gerhardh Oct 20 '17 at 14:45
  • 2
    It uses the [*comma operator*](https://stackoverflow.com/questions/52550/what-does-the-comma-operator-do). `i` is first incremented, and the return value of that is discarded, then the (already-incremented) value of `i` is given as the argument to `reverse`... – Antti Haapala -- Слава Україні Oct 20 '17 at 14:46
  • Now got it, thanks @AnttiHaapala – Shree Wankhede Oct 20 '17 at 14:49
  • so `i++` would increment `i` and the value of the expression would be the *old* value of `i`. A comma operator is a sequence point - it *forces* any side effect be settled on the left hand side (which here means: incrementing `i`) and *then* evaluates the right-hand side – Antti Haapala -- Слава Україні Oct 20 '17 at 14:54
  • In standard C, you can’t use `return expr;` in a function that returns `void`. The code shouldn’t compile. – Jonathan Leffler Oct 20 '17 at 16:42
  • @JonathanLeffler actually you can return the "result" of another function that returns `void`, like in OP's code. See [this example](https://ideone.com/oghVsU). It also works in C++. Not sure if it's an extension or not though. – Kevin Oct 20 '17 at 17:32
  • @Kevin: Actually, the ISO/IEC 9899:2011 standard says: _§6.8.6.4 The `return` statement — Constraints — ¶1 A `return` statement with an expression shall not appear in a function whose return type is `void`._ The code is wrong according to the standard — hence my use of the expression "In standard C, …". The rule is different in standard C++ (quoting ISO/IEC 14882:2011: §6.6.3 ¶3 _A `return` statement with an expression of type `void` can be used only in functions with a return type of_ cv _`void`; …_ Any C compiler that allows the `return` is flouting the C standard — it's an extension. – Jonathan Leffler Oct 20 '17 at 17:51
  • (The `cv` appears in italics in the standard; I'm not sure of its significance — I'm not sure how a `void` value can usefully be `const` or `volatile` qualified — but it won't affect the conclusion I'm drawing.) – Jonathan Leffler Oct 20 '17 at 17:53
  • @JonathanLeffler thanks for the info. I guess gcc allows this as an extension then. – Kevin Oct 20 '17 at 17:53
  • @Kevin: Yes. GCC allows lots of things as extensions, unless you hold it to the standard with `-std=c11 -pedantic` (for some choice of standard). This is the sort of thing that goes to emphasize that C and C++ are two distinct languages, albeit closely related. It's not an unreasonable extension. It _is_ an extension, though. – Jonathan Leffler Oct 20 '17 at 17:57

2 Answers2

7

The expression (i++, i) uses the comma operator -> it first evaluates the left hand side and then the right hand side, the result is that of the right hand side. As this operator also introduces a sequence point, the result is well-defined: it's the value of i after incrementing it.

In this example, it's just needlessly confusing code because it has the exact same result as just writing reverse(++i); (or even reverse(i + 1); which would better match a functional/recursive approach).

  • You might note that the final `return` in the function is not valid as [standard C](https://stackoverflow.com/questions/46851616/the-following-c-code-gives-output-1-2-3-4-5-how-the-code-is-executed?noredirect=1#comment80656721_46851616) — the keyword should simply be omitted. – Jonathan Leffler Oct 20 '17 at 18:06
  • As an aside here - if you pre/post-increment a variable in an expression, you typically cannot re-use the same variable in that expression, since it's undefined what order they'll be evaluated in (`some_arr[i++] + some_arr[i]` might evaluate `[i++]` before or after evaluating `[i]`), since that's up to compiler optimizations. The exception to this is the comma operator. – Cassandra Fox Oct 20 '17 at 18:31
-1

As it was already rightly pointed out by Felix, it is using the comma operator. You can simply write reverse(i++) or reverse(++i) or reverse(i+1) that'll do!

Prashanthv
  • 109
  • 7
  • 1
    What is this answer supposed to add that Felix's answer (that you mentioned) doesn't already have? And this answer is wrong anyway since `reverse(i++)` *won't* work. – Kevin Oct 20 '17 at 17:37