-4

Following program I saw on some webpage while studying C Language Interview questions, I want to know whether my analysis is correct or not?

 #include<stdio.h>
 #include<stdlib.h>

 void main(int j)
 {
     printf("%d\n",j);
     (&main + (&exit - &main)*(j/1000))(j+1);
 }

My analysis is that initially the argument in the main is argument count so first of all 1 will get printed on the screen, next there is a recursive conditional call to main here (&main + (&exit - &main)*(j/1000))(j+1); In this &exit is greater than &main, so we obtain some value here, it is multiplied with j/1000 means until j is less than 1000 value of (&exit - &main)*(j/1000) will be zero, ultimately main function gets called so the numbers from 1,2,3,-----1000 will get printed.

Once j becomes 1001 the value of (&exit - &main)*(j/1000) will become (&exit - &main)*1 and the address will be (&main + &exit - &main)(j+1); i.e. the address of exit function so the program gets exit printing 1 to 1000.

This is my analysis about this program I want to know whether my analysis about this program is correct or not.

  • Thank you anton there you are providing one more argument (547) with file name so argument count is 2 so the values are getting printed from 2 to 10. Is my analysis correct – Vinayak Indian Jan 06 '15 at 17:19
  • 5
    This is a stupid interview question, that have to rely on implementation-specific behavior of a specific compiler, linker and runtime environment combination. Any deviation (even such things like optimizations and minor version change) will lead to undefined behavior. – Some programmer dude Jan 06 '15 at 17:22

3 Answers3

1

The program has undefined behaviour because additive operator - is not defined for function pointers.

Moreover the order of functions in the resulted object file is undefined.

Also function main shall have return type int.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Oops -- that is mentioned in the comments :P – Jongware Jan 06 '15 at 18:22
  • is this what you mean `When two pointers are subtracted, both must point to elements of the same array object or just one past the last element of the array object (C Standard, 6.5.6 [ISO/IEC 9899:2011]); the result is the difference of the subscripts of the two array elements. Otherwise, the operation is undefined behavior` – Meninx - メネンックス Jan 06 '15 at 18:34
0

j/1000 will return 1 only when j >= 1000

Then

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

will become

&main + &exit - &main = &exit;

Until then

main() will be called recursively

with(j+1) as parameter

Gopi
  • 19,784
  • 4
  • 24
  • 36
0

I encountered the same example a few days before and had spent time to understand it. I am very happy to see someone else who came across the same example if not the same webpage :)

let's analyze the code line by line

First LINE

 void main(int j)

I guess if you change the line above into void main(int argc) you will maybe know that j will hold exactly the same value of argc which is 1 as no arguments will be entered while executing the program In fact the first parameter in main() function will hold always the number of arguments entered to the program including the name of the program

so if I write

./exeProgram // j contains 1

j will contain 1 but if you execute with an extra argument it will hold 2

 ./exeProgram arg1 // j contains 2

Second LINE

 printf("%d\n",j);

this is a simple instruction that print the value of j so let's move to the third line the most important

Third LINE

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

what the statement here is trying to do is executing the main() again and again (in a recursive way) to execute the instruction in a specific number of time

let's see the expression &main + (&exit - &main)*(j/1000) : the first term that will be executed will be (&exit - &main)*(j/1000) here as j is an integer and so 1000 so the result is always an integer but the problem is that when j holds a value in 1 ... 99 which is < 1000 the return value of j/1000 will be 0

so for j between [1..99]:

&main + (&exit - &main)*(j/1000) becomes &main + (&exit - &main)*(0) which is nothing but &main

**

the problem here is that substracting two pointers which don't point to the same array is considered as an undefined behavior !!

**

I will continue the analysis because the idea and the recursive approach is nice and can be used in other working situations !

so for j=1000 now:

&main + (&exit - &main)*(j/1000) becomes &main + (&exit - &main)*(1) which is &main+&exit-&main which is &exit

so let's summarize

if(j>=1 && j<=99)
&main(j) // will be executed when j<=99 and j>=1
else
&exit(j) // will be executed when j=1000

when the program reaches the 1000 value it will execute the function exit() and stop its execution that's it ! :)

Please note that no need to add the & before the main or exit as the function name refers always to it's address.