Cプリプロセッサを使用して、パラメータタイプのみが変更される関数ファミリを定義したいとします。Cプリプロセッサマクロの拡張連結
#include <stdint.h>
#include <stdio.h>
#define type_vector(t) \
t * t##vector(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
type_vector(int8_t)
type_vector(int32_t)
type_vector(int64_t)
int main() {
int32_t * p;
p = int32_tvector(10, 12);
return 0;
}
これはうまくいきます。
ここで、関数名にint8_tの代わりにi8、int32_tの代わりにi32などの短い型名を使用したいとします。 マクロ関数宣言に2番目のパラメータを追加したくない代わりに、 "短い"型名の単一の定義を持つ。 基本的に、私が書いた最初のものだった:
#define sn_int8_t i8
#define sn_int32_t i32
#define sn_int64_t i64
#define sn(t) sn_##t
#define type_vector(t) \
t * sn(t)##vector(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
type_vector(int8_t)
type_vector(int32_t)
type_vector(int64_t)
int main() {
int32_t * p;
p = i32vector(10, 12);
return 0;
}
しかし、これは、コンパイルされません、次のエラーを与える:私の知る限り理解されるように
error: pasting ")" and "vector" does not give a valid preprocessing token
t * sn(t)##vector(int32_t nl, int32_t nh) \
を、問題が「あるためです) "と"# "を並べて表示します。 だから私は次のようでした:
#define sn_int8_t(f) i8##f
#define sn_int32_t(f) i32##f
#define sn_int64_t(f) i64##f
#define sn2(t,f) sn_##t(f)
#define type_vector(t) \
t * sn2(t,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
type_vector(int8_t)
type_vector(int32_t)
type_vector(int64_t)
int main() {
int32_t * p;
p = i32vector(10, 12);
return 0;
}
そして、これが再び正常に動作します。今
、私は例えば、関数名に接頭辞を追加したいと仮定"remote_"。 SN2が展開されていないよう
は単に
#define type_vector(t) \
t * remote_##sn2(t,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
を置くことは、動作しません。だから私はこれを試してみました:
int32_t * remote_sn2(int32_t,vector)
それを行うにはどのような方法があります:
#include <stdint.h>
#include <stdio.h>
#define sn_int8_t(f) i8##f
#define sn_int32_t(f) i32##f
#define sn_int64_t(f) i64##f
#define sn2(t,f) sn_##t(f)
#define short_name(n,t,f) n##_##sn2(t,f)
#define remote_type_vector(t) \
t * short_name(remote,t,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; \
return v; \
}
remote_type_vector(int8_t)
remote_type_vector(int32_t)
remote_type_vector(int64_t)
int main() {
int32_t * p;
p = remote_i32vector(10, 12);
return 0;
}
基本的に、これはマクロSN2が展開されていないので、私のような宣言を与えることが動作しませんか?
注:私はC++テンプレートを使用したくありません。
一部の人々は魔法のこの種を主張しているが悪である... _flexible配列member_を使用 –
は、はるかに簡単思うになるだろう。残りについて:TL; DR。 [mcve]を提供してください。 – Olaf
"マクロ関数宣言に第2パラメータを追加したくありません" - どうしてですか?非常に頻繁にマクロを呼び出すのではありません。 2番目のパラメータは、 'typedef'なしで複合名(' char * '、' struct thing')を持つ型を使うこともできます。 –