clang と gcc の両方でラムダ式のようなことをする
Web アプリ開発の方は、牛歩ながら janus-webrtc-gateway のデモ画面を Django+Vue.js with Bootstrap に移植していっている。
echotest, videocall, audiobridge となんとか動作するものが移植できたが、 videoroom での複数リモートフィードをシンプルに扱うにはどうしたものか、と考えているところで手が止まっている。。
それはさておき、仕事で gcc 拡張の nested function を使用していたところ、 clang static analyzer でエラーになる問題があったので、とりあえずの回避策をメモしておく。
#if !defined(__clang__) #define LAMBDA(ret_type, ...) \ __extension__ \ ({ \ ret_type __fn__ __VA_ARGS__ \ __fn__; \ }) typedef int (*CALLBACK)(int); #else #define LAMBDA(ret_type, ...) \ ^ret_type __VA_ARGS__ typedef int (^CALLBACK)(int); #endif void dummy(CALLBACK cb, int arg) { printf("%d", cb(arg)); } int main(int argc, char **argv) { dummy(LAMBDA(int, (int arg) { return arg; }), 999); dummy(LAMBDA(int, (int arg) { return arg; }), -1); return 0; }
仕掛けは、 gcc では nested function で実現しているところを、 clang では Apple 拡張の blocks で置き換えている。
ただ、 blocks は関数ではないので関数ポインタを渡せないし、あくまでも今回のコードに対する回避策としての意味しかない。 (そして、コンパイルフラグに -fblocks
が必要になり、 libBlocksRuntime in libblocksruntime-dev をリンクする必要がでる。)
簡単なコールバック程度はラムダ式が使いたいけど、ラムダ式と定義済み関数ポインタを渡す処理が混在すると clang static analyer が使用できなくなる。。。
将来的にでも、 C 言語の標準仕様でなんとか解決できないかなー。