I have a question about functions and pointers to functions....

Why does a C program treat a function call to a function and a function call to a function pointer the same?

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

typedef void (*funcptr)(void);

void myfunc(void)
{
	fputs("Hello, World!\n", stdout);
}

int main(int argc, char**argv)
{
	funcptr MyFunc = &myfunc;

	myfunc();
	MyFunc();

	exit(EXIT_SUCCESS);
}

Program output:

Hello, World!
Hello, World!

When I compile the above program both the call to myfunc() and MyFunc() will produced the same result..."Hello, World" will be displayed. Now when I examine the asm instructions for this program, I find that the compiler was nice enough to dereference the function pointer for me.....Why does the language allow for this? Is there a reason to treat two different entities the same in source code but differently in the resulting asm code?....I hope this makes sense...I await your replies....Gerard4143

> Why does a C program treat a function call to a function and a function call to a function pointer the same?
Because they *are* the same. :) A function name is converted to a pointer to a function before the call operator is applied.

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

78) Most often, this is the result of converting an identifier that is a function designator.

The dereference is implied anyway, so any extra dereferences are redundant and ignored. The following code is 100% confusing, but it is also 100% correct. The 5 extra dereferences are ignored.

void foo() {}

int main()
{
   void (*pf)() = foo;

   (*****foo)();
   (*****pf)();
}

> Why does a C program treat a function call to a function and a function call to a function pointer the same?
Because they *are* the same. :)

By the same, do you mean C treats them the same and handles the difference for you? I ask because the compiled instructions are not the same...

Here's what I'm getting at:

40058d:	48 c7 45 f8 54 05 40 	movq   $0x400554,-0x8(%rbp)
400594:	00 
400595:	e8 ba ff ff ff       	callq  400554 <myfunc>
40059a:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
40059e:	ff d0                	callq  *%rax

Line 0x400595 is the first function call
and lines 0x40059a and 0x40059e are the second.

> I ask because the compiled instructions are not the same...
The C standard does not impose any requirements on intermediate assembly or machine code. As long as the "as if" rule is maintained, the compiler can do anything it wants under the hood.

Edited 6 Years Ago by Radical Edward: n/a

> I ask because the compiled instructions are not the same...
The C standard does not impose any requirements on intermediate assembly or machine code. As long as the "as if" rule is maintained, the compiler can do anything it wants under the hood.

So....By the same, do you mean C treats them the same and the compiler handles the difference for you?

Edited 6 Years Ago by gerard4143: n/a

Ed would say that there is no difference because the whims of the compiler are irrelevant when it comes to the validity of a program. The program *has* to behave a certain way, regardless of how the compiler makes it happen.

Your question was about why C as a language treats functions and function pointers the same when called. Ed says how the compiler handles things is irrelevant because that behavior is a requirement at the language level. The abstract machine described by the standard is all that matters, not how actual compilers deviate from it while still keeping to the "as if" rule.

> here's a link about referring to yourself in the third person
Edward is not trying to appear narcissistic, but that link will still make good reading. :)

Comments
Thank-you for the narcissistic but still helpful replies

Now the important question....Why does the C standard implement this type of behaviour or is it better left unknown?

That is a question for the comp.std.c newsgroup. It is probably because of existing compilers when the standard was written. Without breaking programs, concessions needed to be made.

That is a question for the comp.std.c newsgroup. It is probably because of existing compilers when the standard was written. Without breaking programs, concessions needed to be made.

For me, its enough to know it exists...Thanks for the replies...in first and third person...Gerard4143

Edited 6 Years Ago by gerard4143: n/a

Why does the C standard implement this type of behaviour or is it better left unknown?

Language specification (aka. standard) is NOT the same as language implementation (by compiler or interpreter).
http://en.wikipedia.org/wiki/Programming_language_specification
http://en.wikipedia.org/wiki/Programming_language_implementation
So - C standard does not *implement* anything, it just defines standard. And How standard will be implemented concretely by compiler/interpreter is only an implementer business.

Language specification (aka. standard) is NOT the same as language implementation (by compiler or interpreter).
http://en.wikipedia.org/wiki/Programming_language_specification
http://en.wikipedia.org/wiki/Programming_language_implementation
So - C standard does not *implement* anything, it just defines standard. And How standard will be implemented concretely by compiler/interpreter is only an implementer business.

Jeez, thanks for clearing that up...

This question has already been answered. Start a new discussion instead.