I am trying to use the stdout stream to print 0x00000000 instead of (nil) and 0x08ffffff instead of 0x8ffffff.
So basically, char *ptr1 = 0x00000000 and char *ptr2 = 0x08ffffff.
When I run
printf("start of address is %p and end of address is %p", ptr1, ptr2);
I get
start of address is (nil) and end of address is 0x8ffffff
I actually found a way around this and I would actually do this:
char *ptr1 = 0x00000000;
char *ptr2 = 0x08ffffff;
printf("start 0x%08x and end 0x%08x\n",ptr1, ptr2);
This generates
start 0x00000000 and end 0x08ffffff
However, the compiler sends the following warning:
warning: format ‘%x’ expects argument of type ‘unsigned int’,
but argument 3 has type ‘void *’ [-Wformat=]
How should I modify printf to adjust the output print?
First, to have any control over how addresses are printed, you must convert them to an integer type. The specifications for printing pointers with %p are inadequate. To do this, you can include <stdint.h> and use the type uintptr_t, which is an unsigned integer type suitable for some work with addresses.
Second, the header <inttypes.h> provides a macro PRIxPTR that provides a printf conversion specifier for printing uintptr_t values in hexadecimal.
Third, you can add a flag 0 and a minimum field width 8 to request the conversion pad with zeros to at least eight digits.
Here is sample code:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
static void PrintAddress(const void *p)
{
uintptr_t u = (uintptr_t) p;
printf("0x%08" PRIxPTR, u);
}
int main(void)
{
char *ptr1 = (char *) 0x00000000;
char *ptr2 = (char *) 0x08ffffff;
printf("Start of address is ");
PrintAddress(ptr1);
printf(" and end of address is ");
PrintAddress(ptr2);
printf(".\n");
}
Better yet, you can adapt the field width to the size of uintptr_t in your C implementation by including <limits.h> and calculating the number of digits needed:
printf("0x%0*" PRIxPTR, ((int) sizeof u * CHAR_BIT + 3) / 4, u);
Note that directly setting pointers to hard-coded constant values, as you do with the initializations of ptr1 and ptr2, is rare. It is generally used in doing special things with hardware. When you are deliberately converting an integer to a pointer, you should use a cast to avoid a compiler warning.
User contributions licensed under CC BY-SA 3.0