gccmacroswarnings

Suppress comparison always true warning for Macros?


I'm wondering if there's a simple / sane way to get gcc to stop throwing this error when the opposing target of the comparison is a macro. Yes, I recognize that with this particular definition of the macro, the comparison is always true, but it obviously doesn't extend to the general case:

#define ROMBOT 0x00000000
#define ROMTOP 0x00002000
...
if (addr >= ROMBOT && addr < ROMTOP) {

simulator.c:517:2: error: comparison of unsigned expression >= 0 is always true

One solution would be something to the effect of:

#if ROMBOT == 0
if (addr < ROMTOP) {
#else
if (addr >= ROMBOT && addr < ROMTOP) {
#endif

But that seems really ungainly / high-maintenance.

Or the related:

#define CHECK_ROM_BOT(_addr) (... etc)

But that quickly escalates into a lot of ugly / unnecessary macros.

Anyone have any ideas?


Solution

  • One possible way is to use two variables which could, perhaps, be changed, thus:

    uintptr_t rombot = ROMBOT;
    uintptr_t romtop = ROMTOP;
    
    if (addr >= rombot && addr < romtop)
    

    If these variables are visible outside the current source file, they could change under circumstances that the compiler cannot see from compiling this file, so it cannot legitimately warn about the comparison.

    #include <stdint.h>
    
    #define ROMBOT 0x00000000
    #define ROMTOP 0x00002000
    
    uintptr_t rombot = ROMBOT;
    uintptr_t romtop = ROMTOP;
    
    extern int check_addr(uintptr_t addr);
    
    int check_addr(uintptr_t addr)
    {
        if (addr >= ROMBOT && addr < ROMTOP) 
            return 1;
        if (addr >= rombot && addr < romtop) 
            return 2;
        return 0;
    }
    $ make xx.o
    /usr/bin/gcc -g -std=c99 -Wall -Wextra -c -o xx.o xx.c
    xx.c: In function ‘check_addr’:
    xx.c:13: warning: comparison of unsigned expression >= 0 is always true
    $
    

    The warning (since I didn't compile with -Werror) appears for your original code and not for the suggested replacement code. You'll need to think about the types of the variables, but uintptr_t is probably reasonable.