Reputation: 1200
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?
Upvotes: 4
Views: 320
Reputation: 311088
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.
Upvotes: 1
Reputation: 60117
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);
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
.Upvotes: 3