Reputation: 60097
When compiled with gcc -Wall -Wextra
, the following code
boolcmp.c:
#include <stdio.h>
int main(void)
{
#define TEST(X) do{if((X)>=0) puts("no minus");}while(0)
TEST(1);
unsigned u = 0; (void)u;
_Bool b = 0; (void)b;
TEST(u); //-Wtype-limits
TEST(b); //-Wbool-compare
}
generates -Wtype-limits
(with -Wextra
) and -Wbool-comapare
(with -Wall
) warnings as marked.
boolcmp.c: In function ‘main’:
boolcmp.c:4:27: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
#define TEST(X) do{if((X)>=0) puts("positive");}while(0)
^
boolcmp.c:8:2: note: in expansion of macro ‘TEST’
TEST(u); //-Wtype-limits
^~~~
boolcmp.c:4:27: warning: comparison of constant ‘0’ with boolean expression is always true [-Wbool-compare]
#define TEST(X) do{if((X)>=0) puts("positive");}while(0)
^
boolcmp.c:9:2: note: in expansion of macro ‘TEST’
TEST(b); //-Wbool-compare
^~~~
Can these warnings be silenced from within the code without pragmas?
Upvotes: 1
Views: 287
Reputation: 60097
My _Generic
-based non-complaining replacement for an X>=0
test:
#define MY_nominus_eh(X) \
_Generic((X)+0LL,llong:my_spos_,ullong:my_upos_,default:my_fpos_)(X)
static inline _Bool my_upos_(ullong X) { (void)X; return 1; }
static inline _Bool my_spos_(llong X) { return X>=0; }
static inline _Bool my_fpos_(ldouble X) { return X>=0; }
//assumes: typedef long long llong;
//typedef unsigned long long ullong;
//typedef long double ldouble;
Thanks to Christian Gibbons for the suggestion.
Later I found out I actually wanted the macro to expand to an integer constant expression (usable in _Static_assert
's) so I had to come up with something different.
The trick I used was to use _Generic
to replace the suspiciously typed variable with an integer constant, which, while also leading to a tautological comparison, did not trigger gcc's warning.
#include <stdio.h>
int main(void)
{
#define TEST(X) do{if( _Generic((X),_Bool:0,default:_Generic(+(X),unsigned:0,\
unsigned long:0,unsigned long long:0,default:X)) >=0) puts("no minus"); else puts("minus"); }while(0)
TEST(1);
unsigned u = 0; (void)u;
_Bool b = 0; (void)b;
TEST(u); //-Wtype-limits
TEST(b); //-Wbool-compare
TEST(-1);
}
Upvotes: 2