Reputation: 364
UPDATE:
This was just something stupid. My PC crashed a few minutes after this, and after restart it throws the same error as to everyone else... Even when I go back to the original version using GIT. I guess something got messed up in the PCs RAM? XD
In C, can a function pointer type be used to declare and define a function?
I did this by mistake, but it worked as expected without throwing any warnings:
init.h:
typedef bool (*InitFunc)(void);
init.c:
#include <init.h>
#include <moduleX.h>
InitFunc initFuncs[N];
bool init(void)
{
...
initFuncs[n] = &moduleX_Init;
...
}
bool initTask(void* Args)
{
initFuncs[n]();
}
moduleX.h:
#include <init.h>
InitFunc moduleX_Init(void);
moduleX.c:
#include <moduleX.h>
InitFunc moduleX_Init(void)
{
...
return true;
}
As you can see, I defined the function moduleX_Init
using the typedef
of the function pointer. It compiled using GCC (arm-none-eabi-gcc) without even an warning and worked as expected.
I only did this by mistake, but when I noticed it, I was wondering if this is actually a compliant way to declare a function or it just happens to work with GCC.
EDIT:
If I do the declaration like this InitFunc moduleX_Init;
, then I get the following error:
incompatible types when assigning to type InitFunc {aka _Bool (*)(void)}' from type '_Bool'
So it seams, that when used in variable declarations, the function pointer types work as if they were a typedef
of the return type. Is this standard behavior, or just the particularity of GCC?
Upvotes: 0
Views: 1067
Reputation: 1765
In C, can a function pointer type be used to declare and define a function?
No. A function pointer is just a pointer. You can use it to call the function is points to, and for any case a pointer can be used
I did this by mistake, but it worked as expected without throwing any warnings
Well, as for the "any warnings" part compilers here disagree with you. For this line:
typedef bool (*InitFunc)(void);
clang 10
compiler says
dsp$ clang -c min.c
min.c:2:16: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
typedef bool (*InitFunc)(void);
^
min.c:2:9: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
typedef bool (*InitFunc)(void);
~~~~~~~ ^
min.c:2:14: error: function cannot return function type 'int (void)'
typedef bool (*InitFunc)(void);
^
2 warnings and 1 error generated.
And gcc 9.3
says
dsp$ gcc -c min.c
min.c:2:15: error: expected declaration specifiers or ‘...’ before ‘*’ token
2 | typedef bool (*InitFunc)(void);
| ^
As for the part "it worked as expected" what your expectations were?
typedef int(*Pfri)(int);
This is fairly common stuff and declares the name Pfri
as a pointer
to a function
that returns an int
and takes one int
as argument, and this time the compilers will be happy with it.
#define N 10
#include <stdio.h>
typedef int(*Pfri)(int);
int plus3(int i) { return i*3; };
int plus4(int i) { return i*4; };
int main(void)
{
Pfri initFunc[N];
printf("fills array of function pointers\n");
for( int i = 0; i<N; i+=2 )
initFunc[i] = plus4, initFunc[1+i] = plus3;
printf("\
For odd indexes, function is \"int plus3(int i) { return i*3; };\"\n\
For even indexes, function is \"int plus4(int i) { return i*4; };\"\n\
Array has %d functions\n", N);
for( int i=0; i<N; i+=1 )
printf("f(%d)=%d\n", i,initFunc[i](i) );
return 0;
}
This program:
fills array of function pointers
For odd indexes, function is "int plus3(int i) { return i*3; };"
For even indexes, function is "int plus4(int i) { return i*4; };"
Array has 10 functions
f(0)=0
f(1)=3
f(2)=8
f(3)=9
f(4)=16
f(5)=15
f(6)=24
f(7)=21
f(8)=32
f(9)=27
Upvotes: 0
Reputation:
No, you cannot use a function pointer typedef to declare or define a function. You can use use to use function pointer typedefs to specify the type of the return value and arguments.
You are declaring moduleX_Init to return a function pointer. Is that what you wanted? @SergeyA already gave you the warning for the assignment and here is the warning you get for moduleX_Init (gcc 8.3.0-6 without any arguments other the input file):
1.c: In function ‘moduleX_Init’:
1.c:6:9: warning: returning ‘int’ from a function with return type ‘InitFunc’ {aka ‘_Bool (*)(void)’} makes pointer from integer without a cast [-Wint-conversion]
return true;
^~~~
Upvotes: 1
Reputation: 62563
Your code is malformed, and there is no way it could have been compiled without warnings. Here is the one I am getting with your code:
<source>: In function 'init': <source>:11:18: warning: assignment to 'InitFunc' {aka '_Bool (*)(void)'} from incompatible pointer type '_Bool (* (*)(void))(void)' [-Wincompatible-pointer-types]
Your declaration
typedef bool (*InitFunc)(void);
InitFunc moduleX_Init(void);
declares a function which returns a pointer to function. By itself, there is nothing wrong with it, but when you try to use it like this:
initFuncs[n] = &moduleX_Init;
You are assigning function pointers with incompatible signatures, as initFuncs[n]
has a type bool (*)(void)
.
Upvotes: 0