printf() with %p

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  #include <stdio.h>
typedef struct {
  int x;
  int y;
} point_t;
typedef struct {
  point_t center;
  int radius;
} circle_t;
int main(int argc, char** argv) {
  circle_t c;
  circle_t* p1 = &c;
  point_t*  p2 = (point_t*)&c;
  int*      p3 = (int*)&c;
  printf("p1: %p\n", (void*)p1);
  printf("p2: %p\n", (void*)p2);
  printf("p3: %p\n", (void*)p3);
  return 0;
}


I am learning from the book "Extreme C". This is a code snippet which shows that the structure pointers are using the same memory address.
The thing I wonder is why to use (void*) if I can use printf() without it like so:

1
2
3
 printf("p1: %p\n", pt1);
 printf("p2: %p\n", pt2);
 printf("p3: %p\n", pt3);


Is it better to cast to a generic pointer or NULL pointer if using the %p?

Thank you.
https://en.cppreference.com/w/c/io/fprintf
The standard requires that pointer values be cast to void* when calling printf.

Not all machines have a single unified pointer representation.
http://c-faq.com/null/machexamp.html

Parameters which match the variadic position (the ...) in any function are not subject to any kind of implicit conversion when you call the function.
printf expects a void*, and you have to manually cast any such pointers because of the ...
Thank you for your explanation. It is a bit complicated to read but it helps. So it is a good practice to use a (void*) pointer.
That was not the point :)
the function *requires* the cast to a void * (I honestly did not know C cared about this! C++ is picky about types, I will defer to Salem on C's needs). If it requires it, you must do it. There is no 'good practice' here, just mechanics, in other words -- if you do not do what is required, it will not work.

Void * are unavoidable (and frequently, invisibly so) in the C I learned, but I have not kept up with the language changes. I recommend you use them only when you need to do so. There are a few (far less, but a few) places where you need them in C++ as well. Using them when you do not need to do so would not be best practice, for sure.
Last edited on
Parameters which match the variadic position (the ...) in any function are not subject to any kind of implicit conversion when you call the function.

Doesnt C perform default argument promotions? For example in C++ an argument of type float would be converted to double.
Topic archived. No new replies allowed.