-2
    #include <stdio.h>
    #include <conio.h>
    int f(int a){
        int i,f=1;
        for(i=1; i<a; i++)
            f=f*i;
        return f;
    }
    void main(){
        int k;
        clrscr();
        int (*u)(int);
        u=&f;
        printf("%d", u);
        getch();
    }

The above code prints 657 on TurboC++ and the output doesnt change with time, So is it not Garbage value?

    #include <stdio.h>
    int f(int a){
        int i,f=1;
        for(i=1; i<a; i++)
        f=f*i;
        return f;
    }
    int main(){
        int k;
        int (*u)(int);
        u=&f;
        printf("%d", u);
        return 0;
    }

And this modified version of the code, returns:

    4199220 on CodeBlocks
    4199728 on DevC++
    134521824 on OnlineIDE
    134513824 on gcc 4.9.2

And these values don't seem to change with different runs. The output of course is Compiler dependent but Please explain how this output is generated?

Aniq55
  • 15
  • 6
  • 4
    Undefined Behavior does undefined and varying things. More news at 11. – Magisch May 02 '16 at 08:47
  • 1
    you're printing out the address of the function f. It doesn't have to ever be any specific value. – xaxxon May 02 '16 at 08:49
  • Also, the right format specifier for this would be %p (and there may also be something about the problems between `void*` and `void(*)()`) – Medinoc May 02 '16 at 08:51
  • NAA but use `int main(void)` instead of `void main()` – Mohit Jain May 02 '16 at 08:56
  • Every day, someone wants undefined behaviour defined:( If you want to know exectly what is happening on your system, then single-step through the assembler instructions yourelf and you will find out. Don't bother posting your results, though, since they only apply to your system and are useless to anyone else. – Martin James May 02 '16 at 09:06
  • Okay. I asked the question only because the answer on two systems matched – Aniq55 May 02 '16 at 09:07

2 Answers2

4

With the statement

printf("%d", u);

you print the pointer u as a decimal number, i.e. you print the value of u, what it points to.

This address can be different since different compilers and linkers might place it in different places, there's no "standard" where to place functions.

Also, since you use the format "%d" to print a pointer, the behavior is technically undefined. To print a pointer you should use the "%p" format, and cast the pointer to void * (see e.g. this printf (and family) reference for more information).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I think he's more interested in why he's getting specific outputs than how printf works. – xaxxon May 02 '16 at 08:49
  • 2
    Converting function pointer to object pointer `void*` is also undefined. You might be better off converting to unsigned integer instead, as that is at least implementation defined. – user694733 May 02 '16 at 09:03
3
printf("%d", u);

In above line u is a pointer to a function. When you interpret this address as an int and print it, the behaviour is undefined.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
  • But why Is that address always coming up to be the same? – Aniq55 May 02 '16 at 08:51
  • Undefined means it can come same, zero, different, crash or may print your name. To be not pedantic, your file may get loaded in memory in same way everytime. – Mohit Jain May 02 '16 at 08:52
  • But that's not happening, I'm trying it from different laptops and doing it again and again but the answer is always 657 on turbo C ++, how can that be called undefined? – Aniq55 May 02 '16 at 08:54
  • @Aniq55 I guess (due to conio.h) the first one is MS-DOS compiled and launched. Others are on a virtualized memory management platform. – LPs May 02 '16 at 08:55
  • I understand the difference but my only problem is if its undefined and random why always the same memory location is allocated to the function??? – Aniq55 May 02 '16 at 08:56
  • Undefined means it may be save, and learning should be to never do such things in production code. Undefined doesn't necessarily mean random. – Mohit Jain May 02 '16 at 08:57
  • If the value is always the same between executions, it's because you don't have Address Space Layout Randomization (ASLR) active on your OS. As for the compiler itself, it has no reason not to put the same code at the same place if nothing else changes. – Medinoc May 02 '16 at 09:05
  • Relate: http://stackoverflow.com/questions/25113267/address-space-layout-randomization-in-c-compilers/25113386#25113386 – Mohit Jain May 02 '16 at 09:06
  • @Aniq55 why don't you find out for yourself by single-stepping through the assembler on your system? – Martin James May 02 '16 at 09:07