﻿# Difference between %p and %x

Functions belonging to the printf function family have the type specifiers "%p" and "%x"\.

* "x" and "X" serve to output a hexadecimal number\. "x" stands for lower case letters \(abcdef\) while "X" for capital letters \(ABCDEF\)\.
* "p" serves to output a pointer\. It may differ depending upon the compiler and platform\.

One specifier is often used instead of another on 32\-bit systems, but it is a mistake\. Here is an example:

```cpp
int a = 10;
int *b = &a;
printf("%p\n",b);
printf("%X\n",b);
```

On a [Win32](https://pvs-studio.com/en/blog/terms/0054/) system, the following result will be printed:

```cpp
0018FF20
18FF20
```

As you may see, the output results for "%p" and "%X" are rather similar\. This similarity leads to inaccuracy in the code and this, in turn, results in errors occurring when you port a program to a 64\-bit platform\. Most often it is "%X" that is used instead of "%p" to output the value of a pointer, and this results in printing of an incorrect value if the object is situated outside the four less significant Gbytes of the address space\. Let us consider the corresponding [64\-bit](https://pvs-studio.com/en/blog/terms/0001/) version of this program:

```cpp
size_t Gb = 1024*1024*1024;
char *a = (char *)malloc(2 * Gb * sizeof(char));
char *b = (char *)malloc(2 * Gb * sizeof(char));
printf("use %%X: a=%X\n", a);
printf("use %%X: b=%X\n", b);
printf("use %%p: a=%p\n", a);
printf("use %%p: b=%p\n", b); 
use %X: a=80000040
use %X: b=40010040
use %p: a=0000000080000040
use %p: b=0000000140010040
```

The pointer value "b" is printed incorrectly when using "%X"\. 

Here is one more example\. Although it looks strange, the code given here in an abridged form was used in a real application in the UNDO/REDO subsystem:

```cpp
// Here the pointers were saved in the form of a string
int *p1, *p2;
....
char str[128];
sprintf(str, "%X %X", p1, p2);
// In another function this string was processed
// in this way:
void foo(char *str)
{
  int *p1, *p2;
  sscanf(str, "%X %X", &p1, &p2);
  // The result is incorrect values of pointers p1 and p2.
  ...
}
```

Manipulation with the pointers using "%X" resulted in an incorrect program behavior on a 64\-bit system\. Note that such errors might occur very rarely\. To diagnose these, and other similar flaws, it is a good idea to use the analyzer [PVS\-Studio](https://pvs-studio.com/en/pvs-studio/)\.

## References

1. [Lessons on development of 64\-bit C/C\+\+ applications\. Lesson 10\. Pattern 2\. Functions with variable number of arguments](https://pvs-studio.com/en/blog/lessons/0010/)\.
1. Knowledge Base\. [How to correctly print a value of the types \_\_int64, size\_t, and ptrdiff\_t](https://pvs-studio.com/en/blog/posts/cpp/k0046/)\.