Store Pointers to Multiple Functions in Array

IAR gives an error: "a value of type "void*" cannot be assigned to an entity of type "tc_channel_ptr"

IAR is justified in doing so. C permits void * to be converted to any other object pointer type, and such conversions are performed automatically by the assignment operator, but C does not make any provision for void * to be converted to function pointer types. The behavior of your assignment is therefore undefined.

GCC exercises an extension in accepting your code. It is within its rights to do so, but it is not valid to infer from its acceptance that the code is strictly conforming or that other compilers must accept it.

Bottom line: your callback registration function should specify the correct type for its third argument:

void tc_register_callback(void *hw, uint8_t channel, tc_channel_ptr cb)
{
    tc0_channel_cb[channel] = cb;
}

I don't see any advantage to declaring cb as a void * instead.


As a separate matter, I strongly agree with your other answer that you should not hide pointer nature behind a typedef. That is a matter of style, however, not code correctness. It is not related to the error you observe.


I would not hide pointers (even the function pointers) behind the typedefs. If you do not, it is very easy to see if something is pointer or not.

typedef void tc_channel_func(uint32_t);
tc_channel_func *tc0_channel_cb[TC_CHANNEL_COUNT];

void tc_register_callback(void *hw, uint8_t channel, void *cb)
{
    tc0_channel_cb[channel] = (tc_channel_func *)cb;
}

or

void tc_register_callback(void *hw, uint8_t channel, tc_channel_func *cb)
{
    tc0_channel_cb[channel] = cb;
}

but the second version can move the problem to another part of the code.