Blame docs/PrintFormatSpecifiers.md

Packit Service fa4841
# Print Format Specifiers
Packit Service fa4841
Packit Service fa4841
## Lookup Table
Packit Service fa4841
Packit Service fa4841
We use the following format specifiers for all \*printf\* and WLog_* functions:
Packit Service fa4841
Packit Service fa4841
| Type               | signed    | unsigned  | octal     | hex       | HEX       |
Packit Service fa4841
| ------------------ | --------- | --------- | --------- | --------- | --------- |
Packit Service fa4841
| signed char        | %hhd      |           |           |           |           |
Packit Service fa4841
| unsigned char      |           | %hhu      | %hho      | %hhx      | %hhX      |
Packit Service fa4841
| short              | %hd       |           |           |           |           |
Packit Service fa4841
| unsigned short     |           | %hu       | %ho       | %hx       | %hX       |
Packit Service fa4841
| int                | %d        |           |           |           |           |
Packit Service fa4841
| unsigned int       |           | %u        | %o        | %x        | %X        |
Packit Service fa4841
| long               | %ld       |           |           |           |           |
Packit Service fa4841
| unsigned long      |           | %lu       | %lo       | %lx       | %lX       |
Packit Service fa4841
| long long          | %lld      |           |           |           |           |
Packit Service fa4841
| unsigned long long |           | %llu      | %llo      | %llx      | %llX      |
Packit Service fa4841
| size_t             |           | %"PRIuz"  | %"PRIoz"  | %"PRIxz"  | %"PRIXz"  |
Packit Service fa4841
| INT8               | %"PRId8"  |           |           |           |           |
Packit Service fa4841
| UINT8              |           | %"PRIu8"  | %"PRIo8"  | %"PRIx8"  | %"PRIX8"  |
Packit Service fa4841
| BOOLEAN            |           | %"PRIu8"  | %"PRIo8"  | %"PRIx8"  | %"PRIX8"  |
Packit Service fa4841
| BYTE               |           | %"PRIu8"  | %"PRIo8"  | %"PRIx8"  | %"PRIX8"  |
Packit Service fa4841
| CHAR               | %"PRId8"  |           |           |           |           |
Packit Service fa4841
| UCHAR              |           | %"PRIu8"  | %"PRIo8"  | %"PRIx8"  | %"PRIX8"  |
Packit Service fa4841
| INT16              | %"PRId16" |           |           |           |           |
Packit Service fa4841
| UINT16             |           | %"PRIu16" | %"PRIo16" | %"PRIx16" | %"PRIX16" |
Packit Service fa4841
| WORD               |           | %"PRIu16" | %"PRIo16" | %"PRIx16" | %"PRIX16" |
Packit Service fa4841
| WCHAR              |           | %"PRIu16" | %"PRIo16" | %"PRIx16" | %"PRIX16" |
Packit Service fa4841
| SHORT              | %"PRId16" |           |           |           |           |
Packit Service fa4841
| USHORT             |           | %"PRIu16" | %"PRIo16" | %"PRIx16" | %"PRIX16" |
Packit Service fa4841
| INT32              | %"PRId32" |           |           |           |           |
Packit Service fa4841
| UINT32             |           | %"PRIu32" | %"PRIo32" | %"PRIx32" | %"PRIX32" |
Packit Service fa4841
| INT                | %"PRId32" |           |           |           |           |
Packit Service fa4841
| UINT               |           | %"PRIu32" | %"PRIo32" | %"PRIx32" | %"PRIX32" |
Packit Service fa4841
| LONG               | %"PRId32" |           |           |           |           |
Packit Service fa4841
| HRESULT            | %"PRId32" |           |           | %"PRIx32" | %"PRIX32" |
Packit Service fa4841
| NTSTATUS           | %"PRId32" |           |           | %"PRIx32" | %"PRIX32" |
Packit Service fa4841
| ULONG              |           | %"PRIu32" | %"PRIo32" | %"PRIx32" | %"PRIX32" |
Packit Service fa4841
| DWORD              |           | %"PRIu32" | %"PRIo32" | %"PRIx32" | %"PRIX32" |
Packit Service fa4841
| DWORD32            |           | %"PRIu32" | %"PRIo32" | %"PRIx32" | %"PRIX32" |
Packit Service fa4841
| BOOL               | %"PRId32" |           |           |           |           |
Packit Service fa4841
| INT64              | %"PRId64" |           |           |           |           |
Packit Service fa4841
| LONG64             | %"PRId64" |           |           |           |           |
Packit Service fa4841
| LONGLONG           | %"PRId64" |           |           |           |           |
Packit Service fa4841
| UINT64             |           | %"PRIu64" | %"PRIo64" | %"PRIx64" | %"PRIX64" |
Packit Service fa4841
| ULONG64            |           | %"PRIu64" | %"PRIo64" | %"PRIx64" | %"PRIX64" |
Packit Service fa4841
| ULONGLONG          |           | %"PRIu64" | %"PRIo64" | %"PRIx64" | %"PRIX64" |
Packit Service fa4841
| DWORDLONG          |           | %"PRIu64" | %"PRIo64" | %"PRIx64" | %"PRIX64" |
Packit Service fa4841
| QWORD              |           | %"PRIu64" | %"PRIo64" | %"PRIx64" | %"PRIX64" |
Packit Service fa4841
| ULONG64            |           | %"PRIu64" | %"PRIo64" | %"PRIx64" | %"PRIX64" |
Packit Service fa4841
Packit Service fa4841
Packit Service fa4841
## Pointers
Packit Service fa4841
Packit Service fa4841
When printing pointers you should cast the argument to ``(void*)``:
Packit Service fa4841
Packit Service fa4841
```c
Packit Service fa4841
rdpContext *pContext;
Packit Service fa4841
fprintf(stderr, "rdp context is %p\n", (void*) pContext);
Packit Service fa4841
```
Packit Service fa4841
Packit Service fa4841
If you need more formatting options cast the pointer argument to `size_t` and use
Packit Service fa4841
any %"PRI*z" format specifier:
Packit Service fa4841
Packit Service fa4841
```c
Packit Service fa4841
rdpContext *pContext;
Packit Service fa4841
fprintf(stderr, "rdp context is %" PRIuz " (0x%" PRIXz ")\n", (size_t) pContext, (size_t) pContext);
Packit Service fa4841
```
Packit Service fa4841
Packit Service fa4841
Packit Service fa4841
## Integer Promotion
Packit Service fa4841
Packit Service fa4841
Remember that integer types smaller than int are promoted when an operation is
Packit Service fa4841
performed on them.
Packit Service fa4841
Packit Service fa4841
Wrong:
Packit Service fa4841
Packit Service fa4841
```c
Packit Service fa4841
UINT8 a, b;
Packit Service fa4841
fprintf(stderr, "a - b is %" PRIu8 "\n", a - b);
Packit Service fa4841
// depending on the system's PRIu8 definition you might get:
Packit Service fa4841
// warning: format specifies type 'unsigned char' but the argument has type 'int'
Packit Service fa4841
```
Packit Service fa4841
Packit Service fa4841
Correct:
Packit Service fa4841
Packit Service fa4841
```c
Packit Service fa4841
UINT8 a, b;
Packit Service fa4841
fprintf(stderr, "a - b is %d\n", a - b);
Packit Service fa4841
// or ...
Packit Service fa4841
fprintf(stderr, "a - b is %" PRIu8 "\n", (UINT8) (a - b));
Packit Service fa4841
```
Packit Service fa4841
Packit Service fa4841
## TCHAR
Packit Service fa4841
Packit Service fa4841
When using `_tprintf` or similar TCHAR formatting functions or macros you
Packit Service fa4841
need to enclose the PRI format defines:
Packit Service fa4841
Packit Service fa4841
```c
Packit Service fa4841
LPCTSTR lpFileName1;
Packit Service fa4841
UINT64 fileSize1;
Packit Service fa4841
Packit Service fa4841
_tprintf(_T("The size of %s is %") _T(PRIu64) _T("\n"), lpFileName1, fileSize1);
Packit Service fa4841
```
Packit Service fa4841
Packit Service fa4841
Since this makes the strings a lot harder to read try to avoid _tprintf if the
Packit Service fa4841
arguments don't contain TCHAR types.
Packit Service fa4841
Packit Service fa4841
Note: If all compilers were C99 compliant we could simply write ...
Packit Service fa4841
Packit Service fa4841
```c
Packit Service fa4841
_tprintf(_T("The size of %s is %") PRIu64 "\n"), lpFileName1, fileSize1);
Packit Service fa4841
```
Packit Service fa4841
Packit Service fa4841
... since the standard says that only one of the character sequences must be
Packit Service fa4841
prefixed by an encoding prefix and the rest of them are treated to have the
Packit Service fa4841
same. However, Microsoft Visual Studio versions older than VS 2015 are not C99
Packit Service fa4841
compliant in this regard.
Packit Service fa4841
Packit Service fa4841
See [How to use stdint types with _tprintf in Visual Studio 2013](http://stackoverflow.com/questions/41126081/how-to-use-stdint-types-with-tprintf-in-visual-studio-2013)
Packit Service fa4841
for more information.
Packit Service fa4841
Packit Service fa4841
Packit Service fa4841
Packit Service fa4841
## Links
Packit Service fa4841
Packit Service fa4841
- [[MS-DTYP] 2.2 Common Data Types](https://msdn.microsoft.com/en-us/library/cc230309.aspx)
Packit Service fa4841
- [Understand integer conversion rules](https://www.securecoding.cert.org/confluence/display/c/INT02-C.+Understand+integer+conversion+rules)
Packit Service fa4841
- [Printf format strings](https://en.wikipedia.org/wiki/Printf_format_string)
Packit Service fa4841
- [C data types - Basic Types](https://en.wikipedia.org/wiki/C_data_types#Basic_types)