Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why it is recommended to cast a pointer to a generic one before printing?

Tags:

c

pointers

printf

OK, I have heard things like you should cast a pointer to a generic one i.e void * before printing it and must practice the use of %p placeholder instead of %d in the printf function for printing them.

I just have a feeling that it might be done to prevent truncation of large addresses while printing or Is it something else? But the point is that if you are on a machine with 64 bit pointers and 32 bit integers; use of %p instead of %d will solely do the job.

Is anyone is aware of any practical situations where this casting technique is helpful?

like image 265
darxtrix Avatar asked Jun 29 '14 06:06

darxtrix


1 Answers

Because the specification of the %p specifier is that it prints a void *. It doesn't know how to print any other type of pointer.

With printf the caller must convert the argument to the right type ; the printf function cannot perform any conversions because it does not have access to the type information about what arguments you actually passed in. It can only assume that you passed the right ones.

C99 7.19.6.1#7

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.

C99 7.19.6.1#9

If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

"Undefined behaviour" means anything can happen. In practice, you probably get away with it if the pointer you pass has the same size and representation as void * does. But you should not rely on undefined behaviour.

On modern systems, all object pointers (i.e. not function pointers) have the same size and representation. If you know you are on such a system, and it is not really important if the program misbehaves, then you probably get away with passing the wrong pointer type.

One place where it would be important is if you try to print a function pointer; as there are modern systems which have function pointers a different size to object pointers. It's not guaranteed that casting a function pointer to void * will be allowed by the compiler, but at least you'll get a compiler error message when you try it.

like image 150
M.M Avatar answered Nov 08 '22 21:11

M.M