2017-09-27 39 views
6

Bu out optimize az ya da çok örnek kod ile Casting a function pointer to another type üzerine açıklama talebi cevabı "iyi" derleyici my_callback_helper() fonksiyonu optimize etmek mümkün olmalıdır ama buldum diyoryardımcı işlevlerini

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); 
} 

https://gcc.godbolt.org onu ve yardımcı fonksiyonunu yapar hiçbir derleyici her zaman just a jump to my_callback_function() (-O3) olsa bile oluşturulan alır:

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 

Yani sorum şu: Standartlarda derleyicilerin yardımcıyı ortadan kaldırmasını engelleyen bir şey var mı?

+0

Deneyimlerimde, derleyiciler, işlev işaretçisinin değeri derleme zamanında belirlense bile, işlev işaretçisi çağrılarında satır içi iş yapmada zayıf bir iş yapma eğilimindedir. Satır içi anahtar kelimeye atlamayı deneyebilirsiniz. Bildiğim kadarıyla, standartta optimizasyonu önleyen hiçbir şey yok. – Lundin

cevap

3

Standartta bu optimizasyonu doğrudan engelleyen hiçbir şey yok. Fakat pratikte, "tam bir resme" sahip olmadıkları zaman derleyiciler için her zaman mümkün değildir.

my_callback_helper adresinin adresini aldınız. Yani derleyici bunu kolayca optimize edemez çünkü ne do_stuff onunla ne yaptığını bilmiyor. do_stuff'un tanımlandığı ayrı bir modülde, derleyici, bağımsız değişkeninin (my_callback_helper) yerine my_callback_function numarasını kullanabileceğini/kullanabileceğini bilmez. Tamamen my_callback_helper'u en iyi duruma getirmek için, derleyici do_stuff'un ne yaptığını bilmek zorundadır. Ancak do_stuff, tanımı derleyici için mevcut olmayan bir dış işlevdir. Bu nedenle do_stuff ve tüm kullanımları için bir tanım sağlarsanız, bu tür bir optimizasyon gerçekleşebilir.

+1

Bu ayrıca derleme ve "link" adımları sırasında bağlantı zaman optimizasyonu (GCC ile -flto) kullanılarak yeniden yapılmalıdır. – dbrank0

+0

Belki işaretçi karşılaştırma olasılığı nedeniyle yasak olduğunu düşünüyorum. 'do_stuff()', alınan göstergeyi 'my_callback_function()' ile karşılaştırmaya çalışıyor olabilir. Optimizasyon açıkken, karşılaştırma 'my_callback_function == my_callback_helper' diyecek ve iki farklı nesnenin aynı adrese sahip olması yasal olmayabilir. Eğer yasadışıysa, o zaman bu biraz talihsiz bir şeydir, zıplama ortadan kaldırılamaz. Belki de fn-cast'lerin tanımlanmadan ziyade uygulama tanımlı olması daha iyi olur. – PSkocik