This version1 of the code is a recursive function to print n to 0 values, but there is no return statement, is it using the return value of printf

The version 2 of the code prints from 0 to n,and it worked even if we remove the return keyword as shown in version 3

help me understand the hidden things in the version1 and version3

Version 1

void print(int pme)
{
	if(pme >= 0)
	{
		printf("%d",pme);
		print(pme -1);
	}
}

version 2

int print(int pme)
{
	if(pme == 0)
		return printf("%d,",pme);
	else
	{
		print(pme-1);
		return printf("%d,",pme);
		
	}
}

version 3

int print(int pme)
{
	if(pme == 0)
		printf("%d,",pme);
	else
	{
		print(pme-1);
		printf("%d,",pme);
		
	}
}

Sounds like homework...Is it?

well, its not homework but i am doing it at home

This version1 of the code is a recursive function to print n to 0 values, but there is no return statement, is it using the return value of printf

The version 2 of the code prints from 0 to n,and it worked even if we remove the return keyword as shown in version 3

help me understand the hidden things in the version1 and version3

I'm not sure I understand what you mean by "hidden things", but I'll try to clear up some confusion.

In version 1 you say it is using the return value of printf, this is not true. It is a void function and by default returns no value. You are simply printing the value of 'pme' at this instant of execution and making the recursive call until your terminating condition is true. Then the stack unwinding commences and no value is returned.

version 2 is doing what you said version 1 is. Specifically, it is returning the number of characters printed as the stack unwinds.

In version 3 you are doing the same thing as in version 2, only that the return value is implicit. This is poor coding style and dangerous. You should always be explicit with return values.

Edited 6 Years Ago by tucanoj: n/a

Hi

tucanoj is right, I agree with him. There is an another solution

void print4(int pme){ if (pme > 0) print4(pme-1); printf("%d,",pme);}

which saves some if-branches.

What's hidden? Do you mean how does recursiveness function?

When print4 is called with parameter pme, say pme is 3, 3 is pushed on stack. Next 3 > 0 applies so print4 is called with parameter 2 which is also pushed on stack before print4(2) is executed. 2 > 0 applies too so print4 is called with param 1 which is pushed on stack too and print4(1) will be executed. Finally 1 > 0 applies and 0 is pushed on stack then print4(0) will be executed.

Now if(pme > 0) doesn't apply anymore and print4(-1) will not be executed. Printf now prints the actual parameter 0. Then the functions returns back to caller (which was print4(1)) and there value 1 of actual parameter will be printed out and so on.

The printed sequence is 0 1 2 3.

There is a further hidden thing: Because the actual parameters of function calls are pushed on stack before a function call is executed, the same sequence appears on stack:
0
1
2
3
If function returns to caller, the upper stack value will be removed. Without this stack mechanism recursive function calls would be impossible.

I hope that I could clarify a little of hidden things.

-- tesu

Edited 6 Years Ago by tesuji: n/a

Hi

tucanoj is right, I agree with him. There is an another solution

void print4(int pme){ if (pme > 0) print4(pme-1); printf("%d,",pme);}

which saves some if-branches.

What's hidden? Do you mean how does recursiveness function?

When print4 is called with parameter pme, say pme is 3, 3 is pushed on stack. Next 3 > 0 applies so print4 is called with parameter 2 which is also pushed on stack before print4(2) is executed. 2 > 0 applies too so print4 is called with param 1 which is pushed on stack too and print4(1) will be executed. Finally 1 > 0 applies and 0 is pushed on stack then print4(0) will be executed.

Now if(pme > 0) doesn't apply anymore and print4(-1) will not be executed. Printf now prints the actual parameter 0. Then the functions returns back to caller (which was print4(1)) and there value 1 of actual parameter will be printed out and so on.

The printed sequence is 0 1 2 3.

There is a further hidden thing: Because the actual parameters of function calls are pushed on stack before a function call is executed, the same sequence appears on stack:
0
1
2
3
If function returns to caller, the upper stack value will be removed. Without this stack mechanism recursive function calls would be impossible.

I hope that I could clarify a little of hidden things.

-- tesu

as there are no return statements, in the solution you gave, so does it means that stack unwinding is independent of the return statement.

the functions returns back due to stack unwinding.

one more thing, what all things are stored in the stack while pushing in the stack (function call)

as there are no return statements, in the solution you gave, so does it means that stack unwinding is independent of the return statement.

the functions returns back due to stack unwinding.

one more thing, what all things are stored in the stack while pushing in the stack (function call)

Hi mithunp

To clarify what happen if a C function is called, let's analyse what will happen if this function int fun (int a, double b) is to execute.

1. Just before the call
First, the calling program saves the values of EAX, ECX and EDX on the stack

Then the value of last actual parameter b is pushed on the stack. Next follows parameter a.

Finally contains of EBP register is pushed which is now on top of stack.

2. Now we enter function fun().
All local variables locally defined in fun will also be created on the stack. Then some calculation is done, especially the return value is calculated.

3. Just before leaving function fun
All locally defined variables are poped from stack (partly unwinding)

Important: the return value is passed back in EAX register and not on the stack. This is true as long as the length of the return value is less or equal 4 bytes (if greater, capacity of EAX would be exceeded).

Longer return values will be passed back by an extra actual parameter which is automatically generated if its length exceeds 4 bytes and which is an address. In such case the function fun would look like: int fun (*extra_parameter, int a, double b).

Therefore, return values only affect the contains of the stack by an additional address if return values are longer than 4 bytes.

Function fun() also restores the registers EBX, ESI and EDI before leaving.

4. Now again back in calling program
First, all actual parameters, in our example a and b, are poped from stack (final unwinding). Then, usually the return value transferred via EAX register will be saved.

There is something more detail work to be done inside the function fun to set up a complete stack frame.

I hope I have explained this somewhat understandably. (As for an assembly programmer
dealing with such calling mechanisms is daily job)

-- tesu

Edited 6 Years Ago by tesuji: n/a

Comments
Excellent post

looks like they don't work the same.
you either print 1 2 3 4.......... or you print ..........4 3 2 1
which do you intend to print? your end condition will quit you out for all 3.
it doesn't look like you'll be going deep enough for a stack overflow.

This article has been dead for over six months. Start a new discussion instead.