c - Why have a "warning" when initializing an array of function pointers? -


i try initializing array of function pointers , have "warning":

ring-buffer.c:57:19: warning: assignment incompatible pointer type [enabled default] rbufp->rbfunc[0] = &rbufpush;                  ^ 

but neighborhood's ok:

/*typedef func pointer*/ typedef rbretcod_t (*rbfunc)();  /*rbufp*/ typedef struct {     rbufsiz_t size; /*size , mask*/     rbufdat_t rbufdat;     rbufpoint_t head, tail;     rbfunc rbfunc[3]; /*announce of function pointers array*/ } rbuf_t; rbuf_t *rbufp; ...  /*init func pointers array*/ rbufp->rbfunc[2] = &rbufdel; /*it ok*/ rbufp->rbfunc[1] = &rbufpull; /*it ok*/ rbufp->rbfunc[0] = &rbufpush; /*it bad, why???*/  ...  /*body of functions*/ rbretcod_t rbufpull(unsigned char *dat) {         return rbsucc; } rbretcod_t rbufdel(void) {         return rbsucc; } rbretcod_t rbufpush(unsigned char dat) {         return rbsucc; } 

please explain me why warning occurs in line: rbufp->rbfunc[0] = &rbufpush;, in adjacent rows not there?

see c11 section 6.7.6.3 §14, specifying when 2 function types shall considered compatible:

[...] if 1 type has parameter type list , other type specified function declarator not part of function definition , contains empty identifier list, parameter list shall not have ellipsis terminator , the type of each parameter shall compatible type results application of default argument promotions. [...]

this case rbufpull , rbufdel, not rbufpush unsigned char gets promoted int.

if called rbupush through pointer of type rbfunc, int argument pushed stack, whereas rbufpush expect unsigned char. depending on calling convention , endianness, you'll incorrect results.

one solution change rbufpush take int argument. 1 use cast, ie

rbufp->rbfunc[0] = (rbfunc)&rbufpush; 

you'll need cast correct type rbretcod_t (*)(unsigned char) before calling rbfunc[0].


Comments