This is more or less a request for clarification on Casting a function pointer to another type with example code
struct my_struct;
void my_callback_function(struct my_struct* arg);
void do_stuff(void (*cb)(void*));
static void my_callback_helper(void* pv)
{
my_callback_function(pv);
}
int main()
{
do_stuff(&my_callback_helper);
}
The answer says a "good" compiler should be able to optimize out
the my_callback_helper()
function but I found no compiler at https://gcc.godbolt.org
that does it and the helper function gets always generated even if it's just a jump to my_callback_function()
(-O3):
my_callback_helper:
jmp my_callback_function
main:
subq $8, %rsp
movl $my_callback_helper, %edi
call do_stuff
xorl %eax, %eax
addq $8, %rsp
ret
So my question is: Is there anything in the standard that prevents compilers from eliminating the helper?
There's nothing in the standard that directly prevents this optimization. But in practice, it's not always possible for compilers when they don't have a "full picture".
You have taken the address of my_callback_helper
. So compiler can't easily optimize it out because it doesn't know what do_stuff
does with it. In a separate module where do_stuff
is defined, compiler doesn't know that it can simply use/call my_callback_function
in place of its argument (my_callback_helper
). In order to optimize out my_callback_helper
completely, compiler has to know what do_stuff
does as well. But do_stuff
is an external function whose definition isn't available to compiler. So this sort of optimization may happen if you provide a definition for do_stuff
and all its uses.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With