私は整数型ファミリー(char
、unsigned char
、short
、unsigned short
、int
、...)の値が任意の準拠のCコンパイラでコンパイルすることができますマクロで可能ならばCの負の数であるかどうかを検出しようとしています(したがって、gcc
は許可されていません)警告なし!マクロでの符号量の検出方法は?
私は次のように付属のいくつかの時間後:
#define ISNEG(X) ((X) && (X-1) && ((X <= 0) && (~X >= 0)))
私は、次の例でそれを試してみました:
void
display_result(int arg, int result)
{
printf("ISNEG(%d) is %stive\n", arg, (result ? "nega" : "posi"));
}
void
display_uresult(unsigned int arg, int result)
{
printf("ISNEG(%u) is %stive\n", arg, (result ? "nega" : "posi"));
}
int main()
{
short shrt = 5;
short nshrt = -5;
unsigned short ushrt = 5;
display_result(shrt, ISNEG(shrt));
display_result(nshrt, ISNEG(nshrt));
display_uresult(ushrt, ISNEG(ushrt));
int ni = -5;
int i = 5;
int zero = 0;
display_result(ni, ISNEG(ni));
display_result(i, ISNEG(i));
display_result(zero, ISNEG(zero));
display_result(~zero, ISNEG(~zero)); // wrong
unsigned int uzero = 0;
unsigned int ui = 5;
display_uresult(uzero, ISNEG(uzero));
display_uresult(~uzero, ISNEG(~uzero));
display_uresult(ui, ISNEG(ui));
long int li = -5;
unsigned long int uli = 5;
display_result(li, ISNEG(li));
display_uresult(uli, ISNEG(uli));
long long int lli = -5;
unsigned long long int ulli = 5;
display_result(lli, ISNEG(lli));
display_uresult(ulli, ISNEG(ulli));
return EXIT_SUCCESS;
}
そして、結果は次のとおりです。
ISNEG(5) is positive
ISNEG(-5) is negative
ISNEG(5) is positive
ISNEG(-5) is negative
ISNEG(5) is positive
ISNEG(0) is positive
ISNEG(-1) is negative
ISNEG(0) is positive
ISNEG(4294967295) is positive
ISNEG(5) is positive
ISNEG(-5) is negative
ISNEG(5) is positive
ISNEG(-5) is negative
ISNEG(5) is positive
それは動作しますかなり良いですが、問題は、すべての警告(-Wall -Wextra
)でコンパイルすると、次のようになりますINGのメッセージ:
signedness.c: In function ‘main’:
signedness.c:27:3: warning: promoted ~unsigned is always non-zero [-Wsign-compare]
display_uresult(ushrt, ISNEG(ushrt));
^
signedness.c:4:49: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
#define ISNEG(X) ((X) && (X-1) && ((X <= 0) && (~X >= 0)))
^
signedness.c:41:26: note: in expansion of macro ‘ISNEG’
display_uresult(uzero, ISNEG(uzero));
^
signedness.c:4:49: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
#define ISNEG(X) ((X) && (X-1) && ((X <= 0) && (~X >= 0)))
^
signedness.c:42:27: note: in expansion of macro ‘ISNEG’
display_uresult(~uzero, ISNEG(~uzero));
^
signedness.c:4:49: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
#define ISNEG(X) ((X) && (X-1) && ((X <= 0) && (~X >= 0)))
^
signedness.c:43:23: note: in expansion of macro ‘ISNEG’
display_uresult(ui, ISNEG(ui));
^
signedness.c:4:49: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
#define ISNEG(X) ((X) && (X-1) && ((X <= 0) && (~X >= 0)))
^
signedness.c:49:24: note: in expansion of macro ‘ISNEG’
display_uresult(uli, ISNEG(uli));
^
signedness.c:4:49: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
#define ISNEG(X) ((X) && (X-1) && ((X <= 0) && (~X >= 0)))
^
signedness.c:55:25: note: in expansion of macro ‘ISNEG’
display_uresult(ulli, ISNEG(ulli));
^
だから、私の質問は以下のとおりです。
我々はC言語のすべての可能な整数型の間の負の変数を持っていることを検出するためのより良い方法はありますか?
これらの警告をすべて非アクティブ化せずに(GCCトリックを使用せずに)取り除くにはどうすればよいですか?
[マクロでは、指定された整数型がCで符号付きか符号なしかをテストできますか?](http://stackoverflow.com/questions/7962855/macro-to-test-whether-a-given-整数型の-n-signed-in-c) – WhozCraig
@WhozCraig:私は変数の型ではなく、変数の値について話しています。さらに、変数を指定すると、Cはイントロスペクションを持たないため、変数の型を事前に取得する方法はありません(非標準の拡張を使用している場合を除く)。 – perror
'(X <0)'の何が問題になっていますか?符号なし型のコンパイラ警告ですか? – jxh