Help us understand the problem. What is going on with this article?

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

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

VoQn
デジタルプロダクトデザイナー
http://voqn.github.io
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away