2

What is a function name? What's its relation to a pointer to it?To try to understand these questions, codes below are written:

#include <stdio.h>

int testFunc(void);

void ptrFuncProp(void);

int main(){
    ptrFuncProp();
    return 0;
}

void ptrFuncProp(void){
    int i = 0;
    int (*p_testFunc)(void) = testFunc;

    testFunc();
    (*testFunc)();
    p_testFunc();
    (*p_testFunc)();

    printf("testFunc:\t%d\n*testFunc:\t%d\n",sizeof(testFunc),sizeof(*testFunc));
    printf("p_testFunc:\t%d\n*p_testFunc:\t%d\n",sizeof(p_testFunc),sizeof(*p_testFunc));
    putchar('\n');

    printf("testFunc:\t%c\n",testFunc);
    printf("*testFunc:\t%c\n",*testFunc);
    printf("*p_testFunc:\t%c\n",*p_testFunc);

    for(;*p_testFunc && i<30;i++){
        printf("%c ",*(p_testFunc + i));
        if(i%10 == 9){
            putchar('\n');
        }
    }
}

int testFunc(void){
    int i=0;
    printf("output by testFunc\n");
    return 0;
}

The output is as follows:

output of the program

In the code, a simple function testFunc is defined, and a pointer p_testFunc points to it.As I learned on the internet, I tried four ways to call this function;they all work although I don't exactly understand.

Next 2 lines try to figure out what really are the function name and a pointer of it.One thing I can understand is that p_testFunc is a pointer, so it contains the address of something else;the address is 8 bytes. But why the size of the function name is 1 bytes because I used to think a function name is a const pointer whose content is the address of the start of the function. If the function name is not a pointer, how can it be dereferenced?

After the experiment, the questions are still unsolved.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
jacktown
  • 35
  • 5
  • 1
    `printf("%c ",*(p_testFunc + i));` is UB, if I'm not mistaken. – Sourav Ghosh Jun 02 '17 at 13:50
  • @SouravGhosh You are not. https://stackoverflow.com/questions/5085366/incrementing-function-pointers – Eugene Sh. Jun 02 '17 at 14:01
  • 1
    A function _name_ is an identifier to the compiler and linker. A function _pointer_ points to a function, independent of its name (if properly declared, a function pointer will require that only [the addres of] compatible functions are assigned to it). A function pointer is dereferenced by making a call to it (the compiler dereferences it for you). – Paul Ogilvie Jun 02 '17 at 14:04
  • You're complicating the issue. Most functions are called directly. Occasionally it is necessary to insert a level of indirection between the function and the caller, and that is a function pointer. Like other pointers it contains an address. Unlike other pointers, you don't need * to dereference it. – Malcolm McLean Jun 02 '17 at 14:16
  • Maybe it's too deep for my current learning stage. – jacktown Jun 02 '17 at 14:30

2 Answers2

1

If you just got into C you should grasp at what pointer is first.

"A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before using it to store any variable address".

There is not differece between pointer to a integer/char etc. and a pointer to a function. Its purpose is to point to an address in the memory where ,in this case, the function is stored.

Name of the function on other hand is just how the functions is named. As people suggested in the comments it identify the function in front of the compiler,linker.

how a function is defined:

int ( what the function will return) isEven (the function name) (int number) ( what argument will it accept)
//How it would look like
int isEven (int number){

   //Here goes the body!

}

Just a little overview of the function.

How is the pointer function defined:

int (return type) *(*isEven(Name))(int(input arguments));
//No tips again!
int  (*isEven)(int);

Also I noticed in your code you didnt use any &. Consider the result of the following snipet:

    #include <stdio.h>
void my_int_func(int x)
{
    printf( "%d\n", x );
}

int main()
{
    void (*foo)(int);
    /* the ampersand is actually optional */
    foo = &my_int_func;
    printf("addres: %p \n", foo);
    printf("addres: %p \n",  my_int_func);


    return 0;
}

Note: %p will format you the addresses of what is inputed.

du4ko
  • 101
  • 6
  • I use %p to output the address again,which prove they are all the same address. But how to explain the outcome of sizeof in the origin code. printf("testFunc:\t%p\n",testFunc); printf("*testFunc:\t%p\n",*testFunc); printf("p_testFunc:\t%p\n",p_testFunc); printf("*p_testFunc:\t%p\n",*p_testFunc); – jacktown Jun 03 '17 at 13:43
  • What compiler are you using? Also please explain what do you find suprising about the output, in order for me to be able to explain it better. – du4ko Jun 04 '17 at 07:16
  • I know little about compiler, but the software I use is dev-C++ in win8.1. What surprises me is the size of the function name is 1 while the size of a pointer to function is 8 as you can see in the graph i provide in original question, although the address they represent(or point to) is the same which is the start of the function. – jacktown Jun 04 '17 at 23:35
  • The comment from @Paul Ogilvie says the function name is an identifier; does the identifier just have 1 bytes which lead to the outcome of sizeof operation? – jacktown Jun 04 '17 at 23:40
  • What he ment is that the function **name** is identifier. Pointer size differs a lot, it depends on your IDE, compiler, OS. Size depends on the variable which is pointing to as well. This should be a good read: [link](https://cboard.cprogramming.com/c-programming/108747-size-function-pointer.html) Dont hesitate to ask more questions if you have, and if you found my comments helpfull, upvote/accept my answer :) – du4ko Jun 05 '17 at 06:34
  • Pointer's size is not my problem but the function name's. All the things I did is to figure out what's function name. What's the difference compared to function pointer. – jacktown Jun 05 '17 at 11:26
  • Okay imagine it like that , the function has name, `int funcSum(int a, int b){ return a + b; }` This function's name is funcSum, if we want to create a pointer that points to the address of the function we need to create a separate thing with its own name. `int(*HereGoesTheName)(HereGoesInputArguments)` Did that answer your question? – du4ko Jun 05 '17 at 11:35
  • `int first = 1; int sec = 2; int(*pointer)(int a,int b); pointer = &funcSum; printf("%d ", pointer(first,sec));` If we run this code and asume that funcSum is defined as my previos comment you will see that both pointer and funcSum will do the same, which is sum two numbers. The pointer just points to funcSum but has its own name. – du4ko Jun 05 '17 at 11:46
  • Not getting my point yet. I just don't know how to explain further, maybe I should just keep the question in my mind at present. Thank you any way. – jacktown Jun 05 '17 at 14:22
  • Sorry I am not able to undestand your point. If you found my post helpfull , I will apretiate if you upvote/accept it. Also you can keep it open, and when you clear out the exact question you want to ask, do it here again. I would be more than happy to assist you with it. :) – du4ko Jun 05 '17 at 14:27
0

Function types in C are 'special'. Like array types, you can't really have values of function type, so any use of a an expression of function type in an rvalue context will be (silently) converted into a pointer -- a pointer to the function type.

So whenever you use the name of a function like my_int_func, that will get converted into the same thing as &my_int_func. To go along with this, if you have a call expression where the type of the thing being called is a function pointer type, it will call the pointed at function.

This is why testFunc, *testFunc, &testFunc (and even things like *******testFunc) will all print as the same value when you pass them to a function like printf.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226