-1
// A recursive C program to print all numbers from 1
// to N without semicoolon 
#include<stdio.h>
#define N 10

int main(int num)
{
    if (num <= N && printf("%d ", num) && main(num + 1))
    {
    }     
}

How is this program working ?. Please Explain this

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • 7
    It works poorly, this is horribly written code. It can be simplified by having a sane person writing a loop instead. "without a semicolon" is a useless nonsense requirement. – Lundin Aug 16 '18 at 11:10
  • 3
    and it works very by chance, standard 6.9.1: *If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.* – unalignedmemoryaccess Aug 16 '18 at 11:11
  • 3
    The crap requirements can for example be met by this crap code: `#include #define N 10 #define NO_SEMI(expr) if(expr){} int main (int argc, char *argv[]) { NO_SEMI(argv[0][0]=0) while(argv[0][0]++ < N) { NO_SEMI(printf("%d\n", argv[0][0])) } }` The sad thing is that this code is much better than the code in the question... – Lundin Aug 16 '18 at 11:25
  • 3
    @tilz0R What about 5.1.2.2.3 ".... reaching the } that terminates the main function returns a value of 0." – Support Ukraine Aug 16 '18 at 11:38
  • @4386427 nice catch. Very stupid standard if we have on 2 completely different chapters similar topic. – unalignedmemoryaccess Aug 16 '18 at 11:39

2 Answers2

1

The code in this awful example relies on some fragile assumptions:

main is called with 2 arguments: an int representing the number of arguments, including the program name, and an array of char* containing the argument string terminated by a NULL.

The example assumes that defining main() with a single int argument will produce code compatible with this calling convention, which may or may not be valid and is explicitly described as having undefined behavior by the C Standard (J.2).

If it is valid or works by chance, the int argument received by main will be 1 if the program is called from the command line without arguments.

main() tests if this argument is <= N, is other words if the value is to be printed. If so, it invokes printf("%d ", num), which outputs the decimal representation of num to stdout and returns the number of characters produced, 2 for the first number, which is non zero, so the code goes on and invokes main recursively, passing it the next higher number.

The goes on until all numbers up to N have been printed and the first test in the last recursive call fails.

main then returns 0 (if the compiler is complies with the C99 or a later standard). Each recursive call returns 0 until the initial call returns 0 to the system.

The code is fragile because main is invoked in a non standard way. It would be slightly less ugly to write:

#include <stdio.h>

#define N 10

int main(int argc, char *argv[]) {
    if (num <= N && printf("%d ", num) && main(num + 1, argv)) {}
}

Note however that calling main() recursively is generally considered bad practice.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • [@Lundin comment](https://stackoverflow.com/questions/51875433/how-to-print-a-1-to-n-without-using-semicolon-explain-this-code#comment90703101_51875433) is a counter example to "basically need a recursive function" – chux - Reinstate Monica Aug 16 '18 at 13:15
  • That really does answer the question very well now - thanks for the improvement! – Toby Speight Aug 16 '18 at 20:17
0

As long as the function inside returns a value convertable to bool, it will be accepted also called.

If successful, the total number of characters written is returned. On failure, a negative number is returned.

Above is the return value of printf() function. So yeah printf("%d ", num) will always return true in this case and print at each iteration.