CとFFI
C言語でfoo(int x)をfoo(int x, ...)に変えるのってABI上位互換になるんだったっけ?
(↑のリンク先で返信しているように、)x64の場合はならない。
で、i386の場合は微妙に複雑で、
- cdecl呼び出し規約では実は上位互換にできる
というのは、これらのOSでデフォルトになっているcdecl呼び出し規約はcallerがスタックを復帰すると決まっているので。。
また、cdeclでは可変長引数のための特別な規約は特に無いので、関数が可変長引数を取るかどうか(= 関数プロトタイプが存在するか否か)で呼び出しのシーケンスが変わることもない。
つまり、関数に引数を追加してもABI互換性は保たれる。しかし、追加した引数を省略した場合の内容は単純に不定になるので、実際にこのテクニックを使ってAPIを拡張するのは難しい。
逆に、
- stdcall(Win32)では上位互換にできない
stdcallはcalleeがスタックを復帰するので、自分が消費する以上の引数がスタックに積まれていると事件が起こる。
moshのFFIには現状呼び出し規約を設定する機能が無いので、実はstdcallなAPIは正常に呼べない。(もっとも、msvcrtのCランタイム関数やCコンパイラのデフォルト呼び出し規約はcdeclなので、Win32 APIが呼べない以外は大きな問題は無い。nmoshはこのへんの解決が面倒なので、moshのFFIはpluginを呼ぶためだけに使用することにしている。)