1

I'm just doing some college exercises in C. currently I'm using vscode with C/C++ to code C in my "native environment".

But when I try to print a deferenced value the GCC throws me warnings at compile time. Look at this:

#include <stdio.h>
#include <stdlib.h>

int main (void) {
    
    int x = 10;
    double y = 20.50;
    char z = 'a';

    int *pointer_x = &x;
    double *pointer_y = &y;
    char *pointer_z = &z;

    double sum = *pointer_x + *pointer_y;

    printf("Endereço de x = %i\nValor referência de x = %i\n\n", pointer_x, *pointer_x);

    printf("Endereço de y = %i\nValor referência de y = %f\n\n", pointer_y, *pointer_y);

    printf("Endereço de z = %i\nValor referência de z = %c\n\n", pointer_z, *pointer_z);

    printf("O Valor da soma entre x e y é = %f\n\n", sum);

    getchar();

    return 0;
}

Warnings that I've got:

format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘int*’ [-Wformat=]
format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘double*’ [-Wformat=]
format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘char*’ [-Wformat=]

What am I doing wrong? I really want to display the reference (i don't want do display the adress) value in the second argument, that's why i've used the deference operator. So i don't understand if this warnings are true or not, can anyone help me with this?

Rob
  • 14,746
  • 28
  • 47
  • 65

1 Answers1

3

The warnings are true, and they are for your first argument, not the second one.
That is, the first argument after the format string, which is "argument 1" for printf - which is why the warnings state "argument 2".

You are trying to print the address with %i but you should be using %p:

printf("Endereço de x = %p\nValor referência de x = %i\n\n", (void*)pointer_x, *pointer_x);
printf("Endereço de y = %p\nValor referência de y = %f\n\n", (void*)pointer_y, *pointer_y);
printf("Endereço de z = %p\nValor referência de z = %c\n\n", (void*)pointer_z, *pointer_z);

Edit: as per the comments, the C standard specifies that pointers should also be cast to void * to be used with the %p formatting argument.

Lev M.
  • 6,088
  • 1
  • 10
  • 23
  • 1
    I still get a warning for this, but now it's `warning: format '%p' expects argument of type 'void *', but argument 2 has type 'int *'`. Each pointer should be cast to `void*`. – Fred Larson May 11 '21 at 19:54
  • @FredLarson Even with `-Wall`, my current gcc compilers (apple clang 12.0.5 and linux 4.8.3) render no such warnings. That is, warning-wise, casting `int *` to `void *` for `%p` is not required. What's your config and usage? – Jeff Holt May 11 '21 at 20:02
  • @JeffHolt: It says it's due to `[-Wformat=]`, which may be pulled in by `-Wextra`. See [printf(“%p”) and casting to (void *)](https://stackoverflow.com/q/24867814/10077). – Fred Larson May 11 '21 at 20:04
  • @FredLarson Hmm. Using `-Wformat` and/or `-Wextra` still produces no warnings. When I asked for config, I meant platform and version. – Jeff Holt May 11 '21 at 20:07
  • @FredLarson Not necessary. MinGW says it all. – Jeff Holt May 11 '21 at 20:10
  • @JeffHolt: Ah, it isn't `-Wextra` that does it. It's `-pedantic`. https://godbolt.org/z/49j4ojW3x – Fred Larson May 11 '21 at 20:13
  • @FredLarson Yep. I see it now. And after reading your citation and Eric's, I see that it is supposed to be passed as `void *`. That really should be the only explanation but I was having a hard time believing there existed an implementation where pointer sizes vary by type. My bad. So, Lev really should update his answer to avoid UB. – Jeff Holt May 11 '21 at 20:16