-1

Suppose such a snippet of minimal code:

#include <stdio.h>
int main(void)
{
    int a = 2;
    int b = a;
    printf("a = %d, &a = %d", a, &a);
    printf("b = %d, &b = %d", b, &b);

    return 0;
}

I ran it and get error report as:

test.c:6:31: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat]
        printf("a = %d, &a = %d", a, &a);
                             ~~      ^~
test.c:7:31: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat]
        printf("b = %d, &b = %d", b, &b);
                             ~~      ^~
2 warnings generated.

I assume a = 2 b = 2 is equivalent to a = b = 2, nonetheless the complier remind info hardly to understand.

AbstProcDo
  • 19,953
  • 19
  • 81
  • 138
  • 7
    To print a pointer, use `%p` instead of `%d`. `&a` is not an `int`, but a pointer to an `int`. – Blaze Oct 18 '18 at 14:50
  • 4
    Your title is misleading. As you see by the compile output, these are warnings and produced by another line. – Osiris Oct 18 '18 at 14:51
  • `&a` is pointer to int, hence while printing it use `%p` and typecast as `void*` as [p conversion specifier requires an argument of type void *](https://stackoverflow.com/questions/24867814/printfp-and-casting-to-void) – Achal Oct 18 '18 at 15:00
  • 2
    The compiler helpfully underlines the line that has an error, and spells out its reason in plain English. – n. m. could be an AI Oct 18 '18 at 15:02
  • I have to say that as compiler messages go, that one is particularly helpful and easy to read. – Tim Randall Oct 18 '18 at 15:02
  • Why &a is a pointer? a is allocated a chuck of memory with value 2 stored. &a is the address of the memory, I guess I did not utilize pointer within the code. @Achal – AbstProcDo Oct 18 '18 at 15:06
  • `&a` is of type pointer to `int` because `a` is of type `int`. Often, when we talk about pointers, we are discussing actual variables, but sometimes we are just talking about temporary values -- things created by the compiler as an intermediate value in a larger calculation, or to pass to a function as a parameter (as in this case), or to return from a function. This is getting beyond the scope of the initial question, though. – Tim Randall Oct 18 '18 at 15:34

1 Answers1

4

You're attempting to print a pointer using the %d format specifier, which is used to print an int. That's why you get the warning.

To print a pointer, use the %p format specifier:

printf("a = %d, &a = %p", a, (void*)&a);
printf("b = %d, &b = %p", b, (void*)&b);

Also, be sure to cast the pointer to void *. The reason for this is because not all pointer types necessarily have the same representation, and a variadic function can't properly do a conversion because it doesn't know what the actual type is. So an explicit cast to void * is needed.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 2
    Could you elaborate why the cast to `void*` is recommendable? – Scheff's Cat Oct 18 '18 at 14:55
  • I assume &a is the address of value 2 rather than a pointer. – AbstProcDo Oct 18 '18 at 14:57
  • @riderdragon There is no such thing as the address of value `2`. – Osiris Oct 18 '18 at 14:58
  • @Scheff `%p` expects `void *` and passing another type would invoke undefined behaviour. In C different pointer types also can have different representations. – Osiris Oct 18 '18 at 15:01
  • 1
    @riderdragon `&a` is the address of `a`, which had a value of 2 last time you looked at it – Tim Randall Oct 18 '18 at 15:01
  • Why &a is a pointer? a is allocated a chuck of memory with value 2 stored. &a is the address of the memory, I guess I did not utilize pointer within the code. @Osiris – AbstProcDo Oct 18 '18 at 15:07
  • The complier and answers mentioned pointer, but there are no pointer in the codes with my limited knowledge. @TimRandall – AbstProcDo Oct 18 '18 at 15:11
  • @Osiris I just inspected [`Default argument promotions`](https://en.cppreference.com/w/c/language/conversion#Pointer_conversions). It doesn't mention anything about pointers. So, I believe this is the reason for explicit cast to `void*` is recommendable. – Scheff's Cat Oct 18 '18 at 15:13
  • `&a` is an _expression_ whose _value_ is the address of `a` and whose _type_ is pointer-to-int. – Tim Randall Oct 18 '18 at 15:14
  • 1
    @riderdragon What do you think is returned by the address operator `&`? [Address of](https://en.cppreference.com/w/c/language/operator_member_access#Address_of): _The address-of operator produces the non-lvalue address of its operand, suitable for initializing a pointer to the type of the operand._ – Scheff's Cat Oct 18 '18 at 15:16
  • so &a has it own address of &&a, rephrase it if I want to know the address of a, there should be another memory space to be allocated to store the address? @TimRandall – AbstProcDo Oct 18 '18 at 15:23
  • ty, I am reading more to understand it @Scheff – AbstProcDo Oct 18 '18 at 15:24
  • 1
    @riderdragon `a` is a local variable. `&a` is the address operator applied to `a` providing the address of `a` (type pointer to type of `a`). E.g. `int a;` `&a` will provide a value of type `int*` (with address of `a`). You may store this value (pointer) in another variable: `int a; int *pA = &a;` Now, in turn you can get the address of `pA`. BUT: you cannot get the address of `&a`. The returned value is non-lvalue i.e. nothing with necessary storage which might be addressed. Please, distinguish "address of something" and "something which has an address". `&a` is the former but not the latter. – Scheff's Cat Oct 18 '18 at 15:30
  • 1
    I appreciate it deeply for your patient tutorial. @Scheff – AbstProcDo Oct 18 '18 at 15:35