関数ポインタによる多態性
ポリモルフィズムというとオブジェクト指向言語の専売特許のようなイメージがありますが、C言語でも関数ポインタを使えば同じようなことが実現できるわけです。MySQLのソースを眺めていたらそれらしき部分を見つけたのでメモage。
int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, const char * name, int rep_quick) { ... for (sort_param.key=0 ; sort_param.key < share->base.keys ; rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++) { ... if (sort_param.keyinfo->flag & HA_FULLTEXT) { uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* sort_param.keyinfo->seg->charset->mbmaxlen; sort_info.max_records= (ha_rows) (sort_info.filelength/ft_min_word_len+1); sort_param.key_read=sort_ft_key_read; sort_param.key_write=sort_ft_key_write; sort_param.key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; } else { sort_param.key_read=sort_key_read; sort_param.key_write=sort_key_write; } ... }
このsort_param.key_readとかkey_writeが関数ポインタですね。sort_ft_key_readとかは関数です。インデックスがFULLTEXTの時とそうでない時とで呼ばれる関数が異なります。
良きかな良きかな。とはいうものの、関数ポインタが出てくるとそこでVisualC++のCall Brawser機能がそこで途絶えてしまいソースの流し読みが面倒になるのであまり好きではありませんw まあIDE(Eclipse)によるソース解析を分断するのはJava(JBoss)も同じなんですが。
ムキー! ft_nlq_read_next関数の呼び出し元探すのに30分もかかった!!!1!1
_ft_vft構造体にこの関数へのポインタがあり、_ft_vftはst_ft_infoのメンバであって、これはFI_INFOという別名が付いていて、さらにhandlerクラスにはFI_INFO型のpublic変数があって、こいつ経由でhandlerレベルから呼ばれていたのでした。
リコンパイルにそれなりの時間がかかるから安易にデバッグコードいれるわけにもいかんしなあ。
orz C++による継承の積み重ね + 関数ポインタ = 最凶
呼び出し元へ辿れません。辿れるけれども・・・精神衛生上イクナイ。