明日にはでっかい太陽が昇るかもしれません。

「覚悟」とは!! 暗闇の荒野に!!進むべき道を切り開く事だッ!

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 言語の標準仕様でなんとか解決できないかなー。