3

On testing the code

#include <stdio.h>

 int main()
 {
     char a[5][3];

     printf("a = %p\n", a);
     printf("&a[0] = %p\n", &a[0][0]);
     printf("&a = %p\n", &a);
     printf("*a = %p\n", *a);

     return 0;
  }

it get compiled and giving the output with C mode (http://ideone.com/KD9Wz1):

a = 0xbfd8ea51
&a[0] = 0xbfd8ea51
&a = 0xbfd8ea51
*a = 0xbfd8ea51

While compiling it with strict C99 mode (http://ideone.com/iTACGZ), it results in compilation error:

prog.c: In function ‘main’:
prog.c:7:10: error: format ‘%p’ expects argument of type ‘void *’, but argument 2 has     type ‘char (*)[3]’ [-Werror=format]
prog.c:9:10: error: format ‘%p’ expects argument of type ‘void *’, but argument 2 has    type ‘char (*)[5][3]’ [-Werror=format]
cc1: all warnings being treated as errors

Isn't the above code is valid in C99?

haccks
  • 104,019
  • 25
  • 176
  • 264
  • may be, but you can typecase to `(void*)` – Grijesh Chauhan Jul 25 '13 at 17:21
  • 2
    No, it isn't even valid C89. As the compiler very plainly tells you, you need to convert the pointers to `void *`. – Kerrek SB Jul 25 '13 at 17:21
  • @KerrekSB; I have given the link. See the first one, it is compiling! – haccks Jul 25 '13 at 17:22
  • 1
    http://stackoverflow.com/questions/197757/printing-pointers-in-c – CBIII Jul 25 '13 at 17:23
  • The code doesn't violate any syntax rule or constraint, so a conforming C compiler is not required to issue a diagnostic, but it does have undefined behavior. The "all warnings being treated as errors" message means that the compiler is being invoked (probably with `-Werror`) in a way that causes it to treat even optional diagnostics as fatal. All of this is the same for C90, C99, and C11. And a minor point: `int main(void)` is better than `int main()`, though your compiler probably won't care. – Keith Thompson Jul 25 '13 at 18:10
  • @KeithThompson; I just tried with `-werror` flag on my compiler (GCC 4.7.1) with C99 mode , and still it is giving the correct output (unlike the second link I have posted). – haccks Jul 25 '13 at 18:46
  • 1
    @haccks: It's `-Werror`, not `-werror`. `-Werror` only affects the treatment of warnings; it doesn't enable warnings in the first place. This particular warning is enabled by `-pedantic` along with any of `-std=c90`, `-std=c99`, or `-std=c11` (at least for gcc 4.7.2). Add the casts to fix the problem. – Keith Thompson Jul 25 '13 at 19:06
  • @KeithThompson; Oops,Sorry! That was `-Werror`. And yes, after enabling `-pedantic` flag it is giving the same compilation error. I was not aware of the use of `-pedantic` flag. Thanks for explanation. – haccks Jul 25 '13 at 19:58

1 Answers1

5

You need to insert an explicit cast to void* for any pointer except char*, because the standard guarantees that character pointers and void pointers have identical representation:

6.2.5.27: A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.

Your C89 program has the same problem, but the compiler does not catch it.

Here is the fix:

printf("a = %p\n", (void*)a);
printf("&a[0] = %p\n", &a[0][0]);
printf("&a = %p\n", (void*)&a);
printf("*a = %p\n", *a);
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523