dpaks
dpaks

Reputation: 405

Unexpected output in C

Following is my code:

#include<stdio.h>

int i =5;

int main(i)
{
 if(i<10)
  printf(" %d\n",printf("%d",i+main(++i)));
 return 0;
}

Output

(in both both Ideone.com and Codeblocks)

10 2

9 1

8 1

7 1

6 1

5 1

4 1

3 1

2 1

Can someone explain the reason behind this output? I expected 91, 81, ...., 51. Also, is it true that recursive main() results in unexpected outputs?

PS: This is a program that I had found in an online forum.

Upvotes: 0

Views: 125

Answers (3)

AnT stands with Russia
AnT stands with Russia

Reputation: 320531

Firstly, "implict int" rule has been outlawed a long time ago. int main(i) { ... is not a valid function declaration. The code does not compile in a compliant C compiler.

Secondly, expression i+main(++i) is not sufficently sequenced. It causes undefined behavior. It is illegal to read variable i and independently modify variable i in the same expression without proper sequencing between these actions. The language does not define the behavior in this case.

In practical terms, it is not known whether the value of the first i in i+main(++i) will be read before ++i modifies the value of i or after it. The language makes no guarantees about it. You begin with i equal to 1. For that value of i it is not clear whether the first evaluation of i+main(++i) expresision will be equivalent to 1+main(2) or 2+main(2). This is what happened in your experiment. You for some reason assumed that the first i will be read before i gets incremented. In reality, it worked the other way.

P.S. Formally, C language (as opposed to C++) seems to allow manual calls to main. However, the issue you are having has nothing to do with main being recursive.

Upvotes: 4

David C. Rankin
David C. Rankin

Reputation: 84561

There are a number of undefined bits of the puzzle, but printf is the key to the output. Others have detailed the illegality of the i+main(++i) expression, so let's just look at the printf to analyze the output:

printf(" %d\n",printf("%d",i+main(++i)));

There are two printf statements, where the printf("%d",i+main(++i)) must be evaluated first in order to provide output to the other. So choose your undefined value and plug that in the %d. From here on out the behavior is defined.

man printf - Returned value:

Upon successful return, these functions return the number of characters printed

Given that printf("%d",i+main(++i)) outputs 10 in the first case, the return is 2 for the two characters printed. That value of 2 is passed to printf(" %d\n",.. giving the output for the first pass as:

10 2

Choose your undefined behavior on the second pass and the value for i+main(++i) is 9. The return for printf("%d",i+main(++i)) is now 1 giving your second line of output:

 9 1

And so on and so forth... I cannot explain the undefined 10, 9, 8, ... but the rest makes sense.

Upvotes: 0

Dejan Jovanović
Dejan Jovanović

Reputation: 2125

The argument of main, the variable i, is assumed to be int and it takes over the global i locally. As an argument to main, the first time it is called it has the value "number of arguments"+1. So, if you run your program with no arguments, the first call to main starts with 1. Try running your program with some arguments and you will get a different result.

For me

./a.out a b c
10 2
9 1
8 1 
7 1
6 1
5 1

Understanding the order of evaluation is tricky. Consider the following program and it's output and it might become clearer what the compiler is doing (or not).

#include<stdio.h>

int f(int x) {
  printf("f with x = %d\n", x);
  return x;  
}

int g(int x) {
  printf("g with x = %d\n", x);
  return x;  
}

int main()
{
  int i;

  i = 0;
  printf("%d\n", f(++i) + i + g(++i));

  i = 0;
  printf("%d\n", (f(++i) + i) + g(++i));

  i = 0;
  printf("%d\n", f(++i) + (i + g(++i)));
}

Output

f with x = 1
g with x = 2
4
f with x = 1
g with x = 2
4
f with x = 1
g with x = 2 
5

Upvotes: -1

Related Questions