简体   繁体   中英

function pointer in C, with or without *?

is there difference between with or without * for function pointer in C?

my function pointer declaration like this

typedef void (*DListVisitNode) (Node*, void*);
void DListTraverse( NodeList* , DListVisitNode , void*);

i have code like these

void print_index( Node* node, void* ctx)
{
    printf("index:%d\n", node->index);
}

void* print_content( Node* node, void* ctx)
{
    printf("content:%s\n", node->content);
}
void DListTraverse(NodeList* nodelist, DListVisitNode visit_func, void* ctx)
{
    Node* cur_node = nodelist->headnode;
    while( cur_node != NULL)
    {
        visit_func( cur_node, ctx );
        cur_node = cur_node->nextnode;
    }
}

DListTraverse( nodelist, print_content, NULL );
DListTraverse( nodelist, print_index, NULL );

both of DListTraverse works, but the one with * throws warning like this

warning: passing argument 2 of ‘DListTraverse’ from incompatible pointer type

i would simply delete the * afterward, but what's the difference between them?

print_content is defined as returning a void* ie a generic raw pointer.

print_index is defined as returning void ie without any results.

These are different signatures. Only print_index matches DListVisitNode .

My coding style is to define signature thru typedef like

  typedef void signature_t (int);

Notice that no pointer is involved above. This names the signature of functions with one int argument and no results.

then, when needing pointers to such functions of above signature, use signature_t*

What is true is that the name of a function is like the name of an array; the language implicitly convert these to pointers. So DListTraverse(nodelist, print_content, NULL) is understood like DListTraverse(nodelist, &print_content, NULL)

You should enable all warnings on your compiler; with gcc that means giving -Wall -Wextra as program arguments to the compiler.

You've declared print_content as returning a void * (a pointer), which means it doesn't match DListVisitNode . However, as the function doesn't actually return anything (no return statement), you should be gatting another warning about that.

You may be confused about the difference between the following to typedefs:

typedef void (*DListVisitNode) (Node*, void*);
typedef void * (*DListVisitNode) (Node*, void*);

Or equivalently, between the following two types:

  • void (*) (Node *, void *)

  • void * (*) (Node *, void *)

The former is a pointer to a function returning void , the latter is a pointer to a function returning void * . Each of your print functions is an example of one such function.

Naturally, function pointers of different types are incompatible and not implicitly convertible, as surely this would make no sense: You can't just pretend that a function actually has a completely different signature and expect to be able to call it in any meaningful way. It would be like pretending that a bicycle is a car and then trying to refuel it at a gas station.

typedef void (*DListVisitNode) (Node*, void*);     

Defines a pointer to an function as an type which takes two parameters Node * and void * and returns a void .
Once you use the above statement, DListVisitNode can be used as an type , the exact type is as mentioned above.

void* print_content( Node* node, void* ctx) 

returns a void * and not a void .
C is a strongly typed language, the c standard mandates that any type violations must be reported by the compiler, hence there is a type mismatch and the compiler reports it to you. Basically, if your function doesn't return anything use the return type as void or if you intend to return a particular type then use that specific type as an return type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM