C 言語 マクロ講座 ## 実用編 ― 2007年03月20日 13時00分33秒
各型に適した fread と fwrite を書くことにしよう。今回は、int 型、char 型と double 型を実装する。
% cat read_x.c
#ifndef LIB
#include
#endif
#define FREAD(type) \
size_t fread_ ## type(void *p, FILE* fd) \
{ \
return fread(p, sizeof(type), 1, fd); \
}
#define FWRITE(type) \
size_t fwrite_ ## type(void *p, FILE* fd) \
{ \
return fwrite(p, sizeof(type), 1, fd); \
}
FREAD(int)
FREAD(char)
FREAD(double)
FWRITE(int)
FWRITE(char)
FWRITE(double)
int main()
{
int i = 1;
char c = 'c';
double d = 3.14;
char *filename = "temp.txt";
FILE *in, *out;
out = fopen(filename, "w");
fwrite_int(&i, out);
fwrite_char(&c, out);
fwrite_double(&d, out);
fclose(out);
i = 0; c = 0; d = 0;
printf("i = %d, c = %c, d = %f\n", i, c, d);
in = fopen(filename, "r");
fread_int(&i, in);
fread_char(&c, in);
fread_double(&d, in);
printf("i = %d, c = %c, d = %f\n", i, c, d);
}
% make read_x
cc -O2 -fno-strict-aliasing -pipe read_x.c -o read_x
% ./read_x
i = 0, c = , d = 0.000000
i = 1, c = c, d = 3.140000
プリプロセッサを通して見る。
% gcc -E -DLIB read_x.c
# 1 "read_x.c"
# 1 ""
# 1 ""
# 1 "read_x.c"
# 17 "read_x.c"
size_t fread_int(void *p, FILE* fd) { return fread(p, sizeof(int), 1, fd); }
size_t fread_char(void *p, FILE* fd) { return fread(p, sizeof(char), 1, fd); }
size_t fread_double(void *p, FILE* fd) { return fread(p, sizeof(double), 1, fd);
}
size_t fwrite_int(void *p, FILE* fd) { return fwrite(p, sizeof(int), 1, fd); }
size_t fwrite_char(void *p, FILE* fd) { return fwrite(p, sizeof(char), 1, fd); }
size_t fwrite_double(void *p, FILE* fd) { return fwrite(p, sizeof(double), 1, fd
); }
int main()
{
int i = 1;
char c = 'c';
double d = 3.14;
char *filename = "temp.txt";
FILE *in, *out;
out = fopen(filename, "w");
fwrite_int(&i, out);
fwrite_char(&c, out);
fwrite_double(&d, out);
fclose(out);
i = 0; c = 0; d = 0;
printf("i = %d, c = %c, d = %f\n", i, c, d);
in = fopen(filename, "r");
fread_int(&i, in);
fread_char(&c, in);
fread_double(&d, in);
printf("i = %d, c = %c, d = %f\n", i, c, d);
}
## マクロを使うと C++ のテンプレートの様に、同じ関数の型違いを生成できる。
この様な使い方の欠点は二つ。一、デバッグが少々難しい。二、関数の定義にマクロを使っているため、定義に見えない。
最近のコメント