-1
1. #include<stdio.h> 

    int recursion_check(int i);

 
    main(){

         printf("%d",recursion_check(6));
    }
    
    int recursion_check(int i){
    
    if(i==0)
    return 5;
    
    else{
        recursion_check(i-1);
        }
        
    }

I am calling a function (recursion check) form main function and getting return value but there is no return in else case how i am getting return value?

  • This is just a fluke. Turn on more compiler warnings, like `-Wall` or equivalent, to be informed about potential problems. – tadman Aug 13 '20 at 16:57
  • @Carcigenicate for the record, C doesn't require that at all. You can define a function with an `int` type and no `return`, and it will be a valid C program. C++ on the other hand requires a valid return on all code paths inside a function (except `main`, for compatibility with C). – Blindy Aug 13 '20 at 17:03
  • @Blindy It may be a valid C program, but the results from the function will be indeterminate though right? By "must*, I meant to guarantee expected behavior. – Carcigenicate Aug 13 '20 at 17:05
  • Perhaps, perhaps not. I mean look at the code in OP. As long as you compile it with a "normal" compiler (gcc, msvc, icc) on a regular platform (x86, x86_64), it will always return the expected value, and it won't write to `rax` the same value on every call. It should generate the correct code that an actual optimizing compiler will output for more portable code, without requiring the optimizing compiler. – Blindy Aug 13 '20 at 17:09
  • (ignoring tail-recursive optimizations or dead code elimination of course, a fully optimizing compiler should replace the whole call with a load `5` instruction) – Blindy Aug 13 '20 at 17:10

1 Answers1

3

Welcome to undefined behavior.

The reason why it works on your (supposedly) common computer is because register-sized or smaller integer returns on Intel platforms are done by writing to the RAX/EAX/AX register, and so most compilers on these platforms will avoid using that register for calculations if they can avoid it.

And so when your function eventually gets to a valid return and writes to the RAX register, and then returns out of the entire call chain, the function that initially called your recursive function will read RAX and it'll get the 5 that was written once.

Of course, nothing stops the compiler from not doing this at all. It doesn't have to use RAX, and it doesn't have to avoid using it for other computations. Hence, undefined behaviour.

Blindy
  • 65,249
  • 10
  • 91
  • 131