タイプ指定子に依存しない標準C(C89またはC99準拠)マクロを作成するにはどうすればよいですか?
具体的には、符号付き型と符号なし型の2つの数値、8ビット、16ビット、32ビット、64ビットを比較するマクロを作成したいと思います。
私が探しているのは、次のようなものです。
int c, a , b;
uint16_t p, q, r;
.
.
.
c = min(a, b);
.
.
.
r = min(p, q);
.
.
.
つまり、同じマクロ'min'を使用して、2つの整数(符号付きまたは符号なしの任意の幅)を比較できます。
動作する基本的なマクロは次のように記述できることを私は知っています。
#define min(x, y) (x) < (y) ? (x) : (y)
しかし、これには、式'x'と'y'を2回評価するという副作用が含まれますが、これは望ましくありません。
堅牢性を確保するために、式は1回だけ評価する必要があります。
今まで、私のアプローチは次のように見えます:
#define min(type, x, y) ( { \
type __tmp1 = (x); \
type __tmp2 = (y); \
__tmp1 < __tmp2 ? __tmp1 : __tmp2; } )
int a, b, c;
uint16_t p, q, r;
.
.
.
c = min(int, a, b);
Cコンパイラはエラーをスローします: "expecting; found("、および他の多くの。
このマクロを書き直して、使用法が次の形式になるようにするにはどうすればよいですか。
<result> = min( <type>, <parm1>, <parm2> );
'min'マクロは、その使用法が次のように記述できるようです。
min( <result>, <type>, <parm1>, <parm2> );
しかし、最初の形があればいいのですが。
2012-09-04のアップデート#1:
皆さん、ありがとうございます。あなたの回答/コメントで提供されたすべての情報は、私に可能性のより広い視点を与えてくれました。ええと、私はgccを使用していません。また、私のコンパイラもC11仕様をサポートしていないので、利用できると思われるオプションは次のとおりです。
次の形式のマクロを使用します。
// min( <result>, <type>, <parm1>, <parm2> ); #define min(result, type, x, y) { \ type __tmp1 = (x); \ type __tmp2 = (y); \ result = __tmp1 < __tmp2 ? __tmp1 : __tmp2; } int p, q, r; . . . min(r, int, p, q);
他のアプローチは:
inline char min_char(char x, char y) { return x < y ? x : y; } inline short min_short(short x, short y) { return x < y ? x : y; } inline int min_int(int x, int y) { return x < y ? x : y; } inline long min_long(long x, long y) { return x < y ? x : y; } inline unsigned char min_uchar(unsigned char x, unsigned char y) { return x < y ? x : y; } inline unsigned short min_ushort(unsigned short x, unsigned short y) { return x < y ? x : y; } inline unsigned int min_uint(unsigned int x, unsigned int y) { return x < y ? x : y; } inline unsigned long min_ulong(unsigned long x, unsigned long y) { return x < y ? x : y; } #define min(type, x, y) min_##type(x, y) int p, q, r; . . . r = min(int, p, q);
2番目のアプローチの副作用はありますか?それは、特に「short」および「char」タイプ(符号付きまたは符号なし)に関して、場合によっては予期しない結果をもたらす可能性があります。
改善や提案は大歓迎です。
編集:
ユーザーは以下の関数をどのように指定しますか?
'min_uchar'
彼/彼女は書かなければなりません:
r = min(uchar, p, q);
ユーザーが簡単に書くことができるように、関数'uchar'を書く他の方法はありますか?
r = min(unsigned char, p, q);
この場合、関数に「min_unsigned char」という名前を付けることはできません。これは、Cでは許可されていないためです。他の方法や、ユーザーがマクロ「min」で「unsignedchar」ではなく「uchar」として型を指定する必要がありますか。 '。
2012-09-10の更新:
みんな助けてくれてありがとう。答えを受け入れる必要があるので、エイタンTの答えを受け入れていますが、皆さんからの返事に感謝します。ありがとう。