2

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?

Pat
  • 1,882
  • 2
  • 15
  • 22
  • +1 for compiling with `-Werror` and therefore having to worry about the issue. What are the odds that the ROMBOT address will ever be non-zero? – Jonathan Leffler Sep 25 '11 at 00:55
  • Decent, this is a project I'm putting together for students in an embedded system course. It could be anywhere really depending how things work out in the end. – Pat Sep 25 '11 at 01:04

2 Answers2

0

Another option that someone else thought up is to cast ROMBOT to double in the comparison with 0. This may generate extra machine instructions depending on the compiler. The cast value may not be exact, but according to C11, 6.3.1.4 item 2, it will have the correct sign, which is all you care about.

khw
  • 488
  • 4
  • 10
0

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks, that's a good solution. I'd happier if gcc would track macros and recognize situations such as this, but that's a fight for another day. – Pat Sep 25 '11 at 01:07