#include<stdio.h>
int fun(); /* function prototype */

int main()
{
    int (*p)() = fun;
    (*p)();
    return 0;
}
int fun()
{
    printf("WEB\n");
    return 0;
}

this program is working fine and printing WEB as well int (*p)() = fun; how these two consecutive lines of codes are working please explain.

A function name basically evaluates to a pointer. However, don't quote me on that. What I can say though is that it DOES evaluate to a pointer in context value.

int (*p)();

is a pointer to a function. When fun is equated to p, p, which is a function pointer, now holds the address of function fun.

(*p)();

dereferences this location, through the '*' operator, and invokes it as a function, through the '()' operator.

A function name basically evaluates to a pointer. However, don't quote me on that.

That's a reasonably accurate statement. You can only do two things with a function: call it and take its address. If you're not calling it, then you're taking its address, and the result is a pointer to a function. The only sticky area with saying that a function name evaluates to a pointer is that compilers aren't required to treat the function name in a call as a pointer.

Converting this:

foo();

to this:

(*foo)();

while legal in C, would add an unnecessary level of indirection (assuming it's not optimized away). So you probably won't see compilers treating functions as pointers internally for a call, but conceptually it's OK because the behavior is consistent with that practice.

Anyway, my reason for posting is to add a few things. First, because you can only do two things with a function, the dereference is unnecessary. The compiler will see your function pointer as such and dereference automatically if it's a call:

int (*p)() = fun;

p(); /* OK */

Second, int fun(); isn't a prototype, it's an old-style declaration. There's a subtle but significant difference in that a prototype does argument list checking while an old-style declaration does not. This applies to both the function pointer type and the actual function:

int fun();
int (*p)() = fun;

fun(123); /* Aroo? Compiles fine */
p(123);   /* Aroo? Compiles fine */
int fun(void);
int (*p)() = fun;

fun(123); /* Error! Too many arguments */
p(123);   /* Aroo? Compiles fine */
int fun(void);
int (*p)(void) = fun;

fun(123); /* Error! Too many arguments */
p(123);   /* Error! Too many arguments */

The moral of the story is that in C (unlike C++), an empty parameter list is to be avoided. The correct way to declare a function taking no arguments is with the void parameter list.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.