1

How can I compare a pointer value with a constant memory address?

#define ADR 0x2000
unsigned int * po;
if(po<ADR) { };

Above code works but it gives a warning "comparison between pointer and integer"

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • No, it isnt, The issue is the type of ADR, which is an integer – mjs Mar 13 '15 at 16:38
  • Technically such a comparison isn't meaningful. To be portable, pointer comparisons are only meaningful between two pointers into the same array or allocated block. But if you're, say, on some embedded system where you really do want to compare a pointer to an absolute address, then you should really know enough to understand whether or not to ignore the warning, or cast it away. – Lee Daniel Crocker Mar 13 '15 at 16:42

2 Answers2

1

The issue is that you are actually doing this:

unsigned int * p;
if(p<0x2000) {};

Where 0x2000 is an integer. You can resolve this by using a cast:

#define ADR 0x2000
unsigned int * p;
if(p<(unsigned int*)ADR) {};

Although a better option might be to actually add the cast into the #define like so:

#define ADR ((unsigned int*) 0x2000)

As @Alter Mann (cryptically) points out, technically you should actually cast the pointer to an integer. See this answer for details.

Community
  • 1
  • 1
mjs
  • 2,837
  • 4
  • 28
  • 48
  • 1
    This is not a good solution. If a define represents an address then its type should also represents this. Putting it into the responsibility to the user of casting the number to the correct type is broken by design and error prone. The compiler has no chance to check if the type matches. – vlad_tepesch Mar 13 '15 at 17:27
  • @vlad_tepesch Agree - I phrased it that way to illustrate what was happening, answer updated. – mjs Mar 13 '15 at 17:40
1

make the define to be of type 'pointer'.

#define ADR ((unsigned int*) 0x2000)
unsigned int * po;
if(po<ADR) { };

Also i highly recommend using stdint.h types for such definitions. just in case the compiler and hardware has a different understanding to you of how large an int is.

Also use the correct attributes. defining fix addresses often implies some kind of memory mapped io. then you have to use the volatile to tell the compiler that the content of that address may change surprisingly.

If its an read only address use a const qualifier.

#include <stdint.h>

#define ADR ((volatile uint16_t*) 0x2000)
uint16_t * po;
if(po<ADR) { };
vlad_tepesch
  • 6,681
  • 1
  • 38
  • 80
  • I assume you mean "vary" or "change" surprisingly? This is not really an issue here though, as the OP is comparing the pointers themselves, not the values at that address, although I agree its good practice if ADR is dereferenced – mjs Mar 13 '15 at 16:53
  • 2
    i added the missing word ;) – vlad_tepesch Mar 13 '15 at 17:15