How does the C code that prints from 1 to 1000 without loops or conditional statements work? How does the C code that prints from 1 to 1000 without loops or conditional statements work? c c

How does the C code that prints from 1 to 1000 without loops or conditional statements work?


Don't ever write code like that.


For j<1000, j/1000 is zero (integer division). So:

(&main + (&exit - &main)*(j/1000))(j+1);

is equivalent to:

(&main + (&exit - &main)*0)(j+1);

Which is:

(&main)(j+1);

Which calls main with j+1.

If j == 1000, then the same lines comes out as:

(&main + (&exit - &main)*1)(j+1);

Which boils down to

(&exit)(j+1);

Which is exit(j+1) and leaves the program.


(&exit)(j+1) and exit(j+1) are essentially the same thing - quoting C99 §6.3.2.1/4:

A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".

exit is a function designator. Even without the unary & address-of operator, it is treated as a pointer to function. (The & just makes it explicit.)

And function calls are described in §6.5.2.2/1 and following:

The expression that denotes the called function shall have type pointer to function returning void or returning an object type other than an array type.

So exit(j+1) works because of the automatic conversion of the function type to a pointer-to-function type, and (&exit)(j+1) works as well with an explicit conversion to a pointer-to-function type.

That being said, the above code is not conforming (main takes either two arguments or none at all), and &exit - &main is, I believe, undefined according to §6.5.6/9:

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; ...

The addition (&main + ...) would be valid in itself, and could be used, if the quantity added was zero, since §6.5.6/7 says:

For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

So adding zero to &main would be ok (but not much use).


It uses recursion, pointer arithmetic, and exploits the rounding behavior of integer division.

The j/1000 term rounds down to 0 for all j < 1000; once j reaches 1000, it evaluates to 1.

Now if you have a + (b - a) * n, where n is either 0 or 1, you end up with a if n == 0, and b if n == 1. Using &main (the address of main()) and &exit for a and b, the term (&main + (&exit - &main) * (j/1000)) returns &main when j is below 1000, &exit otherwise. The resulting function pointer is then fed the argument j+1.

This whole construct results in recursive behavior: while j is below 1000, main calls itself recursively; when j reaches 1000, it calls exit instead, making the program exit with exit code 1001 (which is kind of dirty, but works).


https://stackoverflow.com/a/7937813/6607497 explains it all, but for the impatient here is the equivalent (readable) code:

#include <stdio.h>#include <stdlib.h>    void main(int j) {    printf("%d\n", j);    if (i/1000 == 0)        main(j+1);    else        exit(j+1);}

So i guess its obvious how it works.The only real trick being used is the "computed goto" (&main + (&exit - &main)*(j/1000)), evaluating to either main while j/1000 is zero, or exit otherwise (actually if it's 1).

Maybe also note that the program is misusing argc as j, so it will count differently when you pass arguments to the program, and it will most likely crash when you add more than 2000 parameters...