Changes between Version 1 and Version 2 of Printf
- Timestamp:
- 2012-07-10T11:30:44Z (12 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Printf
v1 v2 1 1 = Using `printf` in a safe way = 2 2 3 T o ensure portability among different architectures (namely between 32bit and 64bit), do not use generic directives (e.g. `%d`) for printing types with fixed width or for user-defined types. Use HelenOS-specific macros - such as `PRIu32` (unsigned integer, 32bits) - instead.3 This page describes which type specifiers you shall use when printing special types, such as integers of fixed width or handles returned by various libraries. Do '''not''' use `%d` for everything that looks like an integer. Special types requires special handling. HelenOS system library libc provides macros that hides differences between various architectures and allows you to print special types in platform independent way. 4 4 5 The se macros hide the type modifier only, you can provide width specification and you must enter the leading percentile sign.5 The macros have names similar to `PRIu32` (for `uint32_t` in decimal) or `PRIxn` (for native-size integer in hexadecimal) and you use them instead of the type specifier (see examples below). 6 6 7 7 The `PRI*` macros are defined in two places `/common.h` (yes, in the root directory of HelenOS source) and in `/uspace/lib/c/arch/ARCHITECTURE/include/inttypes.h`. `common.h` is a generated file that appears after you configure your build. 8 8 9 == Fixed width ==10 9 11 The macro is of from `PRI<kind><width>`. `<width>` is one of 8, 16, 32 or 64 or `n` for native width. `<kind>` is summarized in following table. 10 == Integers of fixed width == 11 12 The macro is of form `PRI<kind><width>`. `<width>` is one of 8, 16, 32 or 64 or `n` for native width. `<kind>` is summarized in following table. 12 13 13 14 ||= `<kind>` =||= Meaning =|| … … 16 17 || `x` || unsigned integer, hexadecimal || 17 18 || `o` || unsigned integer, octal || 19 20 For example, to print `uint16_t` in octal, use `PRIo16`. 21 22 == Special integer types == 23 24 ||= Type =||= Directive =|| 25 || `size_t` || `"%zu"` || 26 || `sysarg_t` || `PRIun` / `PRIxn` || 27 || `uintptr_t` || `"%#" PRIxn` || 28 18 29 19 30 == Handles == … … 24 35 Thus, for these handles one should use `PRIun` (makes more sense for integer backed handles) or `PRIxn` (usually for pointers). 25 36 26 27 == Other == 28 29 Following table lists common types and allowed (recommended) ways of printing them. 37 The table below is not exhaustive and serves as a list of hints. 30 38 31 39 ||= Type =||= Directive =|| 32 || `size_t` || `"%zu"` || 33 || `sysarg_t` || `PRIun` / `PRIxn` || 34 || `uintptr_t` || `"%#" PRIxn` || 40 || `fid_t` (fibril id) || `PRIxn` || 41 || `devman_handle_t` (device handle) || `PRIun` || 42 || `thread_id_t` (thread id) || `PRIu64` || 43 || `ipc_callid_t` (IPC call id) || `PRIxn` || 44 || `aid_t` (IPC message id) || `PRIxn` || 35 45 36 46 == Annotating your own printf-like functions ==