printf() with %p

Aug 11, 2021 at 6:21am
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.
Aug 11, 2021 at 8:56am
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 ...
Aug 11, 2021 at 12:19pm
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.
Aug 11, 2021 at 3:07pm
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 Aug 11, 2021 at 3:08pm
Aug 11, 2021 at 3:40pm
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.