0

What does (void*) mean in the following code? I tried removing (void*) typecast but it still works just fine and prints the address of usrInt variable. Can you explain this, please?

#include <stdio.h>

int main(void) {
   int usrInt = 0;    // User defined int value
   int* myPtr = NULL; // Pointer to the user defined int value

   // Prompt user for input
   printf("Enter any number: ");
   scanf("%d", &usrInt);

   // Output int value and location
   printf("We wrote your number into variable usrInt.\n");
   printf("The content of usrInt is: %d.\n", usrInt);
   printf("usrInt's memory address is: %p.\n", (void*) &usrInt);
   printf("\nWe can store that address into pointer variable myPtr.\n");

   // Grab location storing user value
   myPtr = &usrInt;

   // Output pointer value and value pointed by pointer
   printf("The content of myPtr is: %p.\n", (void*) myPtr);
   printf("The content of what myPtr points to is: %d.\n", *myPtr);

   return 0;
}
Giorgi Aptsiauri
  • 355
  • 1
  • 2
  • 11
  • 2
    `%p` works with pointers to `void`. When not casting to it the behavior is technically undefined. – Eugene Sh. Nov 09 '17 at 15:18
  • There is no requirement that a `void*` be the same size in memory as an `int*` -- now is it clear why this is required to avoid undefined behaviour? – Eric Lippert Nov 09 '17 at 15:20

2 Answers2

1

Normally, a cast to or from void * is simply redundant, because this conversion is implicit in C for any data pointer type.

Passing a pointer to a variadic function is a special case that requires the cast.

printf() is a variadic function. The printf() prototype looks like this:

int printf(const char *format, ...);

This means the compiler doesn't see any type declarations for parameters that come after format. Therefore, it doesn't know the type passed should be void *, so the conversion doesn't happen automatically.

Often, omitting the cast won't have any visible effect because in most implementations, all pointers have the exact same internal representation. But the C standard doesn't guarantee that, so implementations are possible where e.g. an int * would have a different representation when it is converted to a void *. If you omit the cast, your code is technically incorrect (it invokes undefined behavior for passing the wrong type for the conversion %p) and would lead to wrong results on platforms where representations of pointers to different types are different.

0

c11: 7.21.6 Formatted input/output functions (p8):

p - The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

msc
  • 33,420
  • 29
  • 119
  • 214