简体   繁体   中英

Function Pointer Declaration

I'm a little confused by the textbook I'm using compared to examples, SO answers, and tutorials I've found online.

The code from the book declares two function pointers but never assigns a value to them, and it doesn't use * in the declaration. The code runs fine and compiles without warning, so I'm a little confused.

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

int main(int argc, char *argv[])
{   
    void    f(int), g(int);

    signal(SIGUSR1, f);
    signal(SIGUSR2, g);

    while(1)
        sleep(1);
}   

void f(int signum)
{   
    printf("Recieved signal %d: SIGUSR1\n", signum);
}   

void g(int signum)
{   
    printf("Received signal %d: SIGUSR2\n", signum);
    exit(SIGUSR2);
}   

The code that I've found online all looks similar to this, with pointer syntax * and an explicit assignment of a function address to the function pointers:

#include <stdio.h> 

void fun(int a) 
{ 
    printf("Value of a is %d\n", a); 
} 
  
int main() 
{ 
    void (*fun_ptr)(int) = &fun; 
  
    (*fun_ptr)(10); 
  
    return 0; 
} 

Is there more than one correct way to declare a function pointer?

Why does the code from the book work?

Is one version "more correct" than the other?

void f(int), g(int); doesn't declare function pointers*. It declares two functions ( f taking int and returning void , and g taking int and returning void ).

( void (*f)(int), (*g)(int); would declare the corresponding function pointers and those would indeed require some initialization before use.)

Declaring functions in a block scope is a little bit confusing because functions cannot be block-local.

In effect it's as if you had void f(int); void g(int); void f(int); void g(int); in filescope, except the block scope limits the scope of the forward declarations:

Example:

void call_f(void)
{
    void f(int);
    f(42);
}

void call_f_again(void)
{
    void f(int); //need to redeclare unless there's also a global decl for f
    f(42);
}

but this scope limitation doesn't really do anything when it comes to functions as all such redeclarations have to be compatible with each other and with a corresponding filescope declaration (whether or not it's provided).

It's simplest (and least confusing) to simply declare functions at filescope.


  • void f(int) is only equivalent to void (*f)(int) when it's used as a function paramater. This is similar to how int f[] in a function parameter is equivalent to int *f .

This declaration

void    f(int), g(int);

declares two functions f and g in the block scope of the function main. They could be declared before main but the author of the code decided to declare them in main because they are used only in main. So there is no declarations of function pointers.

It seems you are confused by the place where the functions are declared.

To make it more clear you could rewrite the program the following way

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

void    f(int), g(int);

// or

void f(int);
void g(int);

int main(int argc, char *argv[])
{   
    signal(SIGUSR1, f);
    signal(SIGUSR2, g);

    while(1)
        sleep(1);
}   

void f(int signum)
{   
    printf("Recieved signal %d: SIGUSR1\n", signum);
}   

void g(int signum)
{   
    printf("Received signal %d: SIGUSR2\n", signum);
    exit(SIGUSR2);
}

The program is valid though the compiler can issue a message that there are redundant function declarations.

The function designators used in these statements

signal(SIGUSR1, f);
signal(SIGUSR2, g);

are implicitly converted to pointers to the functions by the compiler.

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