Edited at

libev で見つけた, ちょっとした extern "C" マクロスニペット

More than 5 years have passed since last update.

最近デザインディレクターみたいなお仕事になって、趣味でしかコード書かなくなってしまい。「じゃあ余暇は思いっきり修験に時間のかかる言語とかをのんびりやるか」と思い至り、C言語を勉強してる VoQn です。

で、 linux kernel のソースとか libev のソースとか読んでたりしてたのですが、 libev の ev.h に小さいけど「あっ、すぐ意味わかったし、なんか小技っぽい」というのを見つけた次第で、ちょっと自分でも使ってみようかなと思うものが。


IF_CPP(expr) マクロ

いや、本当にこれだけなんですけどね。

libev には EV_CPP というマクロで実装されています。


if_cpp_macro.h

#ifndef IF_CPP

# ifdef __cplusplus
# define IF_CPP(expr) expr
# else
# define IF_CPP(expr)
# endif
#endif


使い方


IF_CPP(expr) マクロ使ってない場合(before)


hoge.h

#ifndef _HOGE_H_

#define _HOGE_H_

#ifdef __cplusplus
extern "C" {
#endif

/* … */

#ifdef __cplusplus
}
#endif

#endif


よく見るパターンですね。


IF_CPP(expr) マクロ使った場合(after)


hoge.h

#ifndef _HOGE_H_

#define _HOGE_H_

#include "if_cpp_macro.h"

IF_CPP(extern "C" {)

/* … */

IF_CPP(})

#endif


プラグマ書く量減ったっていうのと、ヘッダファイルから #if プラグマのネストが減りましたね。

ほんっとーに、これだけ。でも #ifdef __cplusplus 何度も書くのだるいなーってきっと libev の人面倒臭かったんだろうな、というのと、案外「純粋にCで書いてるけど C++ 相手に対応するのかったるい」って場合のショートハンドを書く時のパターンに応用できそうだな。と思った。


[追記] Gauche の方がもっと賢かった

Gauche の SCM_DECL_BEGIN がもっとインテリジェンスな感じだった

#ifndef XX_DECL_BEGIN

#ifdef __cplusplus
#define XX_DECL_BEGIN extern "C" {
#define XX_DECL_END }
#else
/* not c++ */
#define XX_DECL_BEGIN
#define XX_DECL_END
#endif

XX_DECL_BEGIN

/* ... */

XX_DECL_END

ああ、こりゃ賢いわ。マネさせてもらってます