-1

This program showing error due to format specifier I've used here while printing the array address in for loop. If I'm using any format specifier except %p for printing the address like %ld, %u, %d etc, it is showing error that are as follows :

prog.c: In function 'main':
prog.c:18:10: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'int *' [-Wformat=]
   printf("Address arr[%d] is %ld\n", i, &arr[i]); 
          ^

Here is my code :

 // C program to demonstrate that array elements are stored 
// contiguous locations 

#include <stdio.h> 
int main() 
{ 
    // an array of 10 integers. If arr[0] is stored at 
    // address x, then arr[1] is stored at x + sizeof(int) 
    // arr[2] is stored at x + sizeof(int) + sizeof(int) 
    // and so on. 
    int arr[5], i; 

    printf("Size of integer in this compiler is %lu\n", sizeof(int)); 

    for (i = 0; i < 5; i++) 
        // The use of '&' before a variable name, yields 
        // address of variable. 
        printf("Address arr[%d] is %ld\n", i, &arr[i]); 

    return 0;

I am not able to understand why %p is used here and what can I use to make my program error free

user7860670
  • 35,849
  • 4
  • 58
  • 84

2 Answers2

0

A long int is not the same as an address. You should use:

printf("Address arr[%d] is %p\n", i, (void *)&arr[i]); 

Note that using any other specifier than %p makes the program (at least) dependent on the architecture. On some architectures the address is 16 bits and on other architectue it is 32 or 64 bits. So for each of these architectures you would need to use a different specifier to handle the different width. %p solves this for you.

The standard requires the argument to be a pointer to void (C11, 7.21.6.1), therefore the cast.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • Not sure why this has been down-voted - it was the first answer and it appears to be correct ? – Paul R Apr 22 '19 at 08:55
  • 1
    @PaulR, not sure either. Someone disappointed he/she wasn't the first or so? – Paul Ogilvie Apr 22 '19 at 08:59
  • 1
    I guess the question is actually "why do I need %p and why do other specifiers produce a warning ?", rather than "how do I fix this warning ?", but the answer is still essentially correct. – Paul R Apr 22 '19 at 09:08
  • if you are using %p then there's no need of typecasting because program is running successfully. what I want to know that why don't we use %x instead of %p if both are the same. – Ashok Pandey Apr 22 '19 at 09:10
  • 2
    @AshokPandey, the fact that the program appears to run successfully does not mean the program is correct. The standard mandates the casting to `void *`. – Paul Ogilvie Apr 22 '19 at 09:12
  • @PaulOgilvie I agreed to your suggestion but how we'll get to know The standard mandates if compiler will not show any error messages. reply as if you are answering a newbie. – Ashok Pandey Apr 22 '19 at 09:19
  • @AshokPandey Use the `-pedantic` flag if you wish to see a compiler diagnostic assuming you are using GCC – Spikatrix Apr 22 '19 at 09:29
  • @Spikatrix but I am coding online at GEEKSFORGEEKS platform. is there any possibility to do it what u said. – Ashok Pandey Apr 22 '19 at 09:35
  • @AshokPandey I've checked their online compiler but did not see any way to modify the compiler flags and options. So I don't think it is possible to do it there. – Spikatrix Apr 22 '19 at 09:39
  • @Spikatrix yeah that's why I am not able to do anything there what you said.as I'm learning DS from there – Ashok Pandey Apr 22 '19 at 09:44
  • @AshokPandey I suggest trying out programs locally on your machine. If you insist on online compilers, I'd suggest better ones such as [rextester](https://rextester.com/l/c_online_compiler_gcc) – Spikatrix Apr 22 '19 at 09:45
0

The standard provides "%p" for use in printing a pointer address, and it expects the type provided to be void*. Your code can be reworked to properly use "%p" as follows:

#include <stdio.h> 

int main (void) 
{ 
    int arr[5], i; 

    printf ("Size of integer in this compiler is %lu\n", sizeof(int)); 

    for (i = 0; i < 5; i++) 
        printf ("Address arr[%d] is %p\n", i, (void*)&arr[i]); 

    return 0;
}

Example Use/Output

$ ./bin/ptraddrarr
Size of integer in this compiler is 4
Address arr[0] is 0x7ffe251cac50
Address arr[1] is 0x7ffe251cac54
Address arr[2] is 0x7ffe251cac58
Address arr[3] is 0x7ffe251cac5c
Address arr[4] is 0x7ffe251cac60

Not recommended, but you can use a "0x%lx" format specifier to obtain the same output, e.g.

        printf ("Address arr[%d] is 0x%lx\n", i, (unsigned long)&arr[i]); 

But, don't, use the proper format specifier provided expressly for this purpose.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85