Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libc / docs / dev / printf_behavior.rst
blob29b1b17ebaecb0a42337a3fbef8b27953b959afb
1 ====================================
2 Printf Behavior Under All Conditions
3 ====================================
5 Introduction: 
6 =============
7 On the "defining undefined behavior" page, I said you should write down your
8 decisions regarding undefined behavior in your functions. This is that document
9 for my printf implementation.
11 Unless otherwise specified, the functionality described is aligned with the ISO
12 C standard and POSIX standard. If any behavior is not mentioned here, it should
13 be assumed to follow the behavior described in those standards.
15 The LLVM-libc codebase is under active development, and may change. This
16 document was last updated [August 18, 2023] by [michaelrj] and may
17 not be accurate after this point.
19 The behavior of LLVM-libc's printf is heavily influenced by compile-time flags.
20 Make sure to check what flags are defined before filing a bug report. It is also
21 not relevant to any other libc implementation of printf, which may or may not
22 share the same behavior.
24 This document assumes familiarity with the definition of the printf function and
25 is intended as a reference, not a replacement for the original standards.
27 --------------
28 General Flags:
29 --------------
30 These compile-time flags will change the behavior of LLVM-libc's printf when it
31 is compiled. Combinations of flags that are incompatible will be marked.
33 LIBC_COPT_STDIO_USE_SYSTEM_FILE
34 -------------------------------
35 When set, this flag changes fprintf and printf to use the FILE API from the
36 system's libc, instead of LLVM-libc's internal FILE API. This is set by default
37 when LLVM-libc is built in overlay mode.
39 LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
40 -----------------------------------
41 When set, this flag disables support for the POSIX "%n$" format, hereafter
42 referred to as "index mode"; conversions using the index mode format will be
43 treated as invalid. This reduces code size.
45 LIBC_COPT_PRINTF_INDEX_ARR_LEN
46 ------------------------------
47 This flag takes a positive integer value, defaulting to 128. This flag
48 determines the number of entries the parser's type descriptor array has. This is
49 used in index mode to avoid re-parsing the format string to determine types when
50 an index lower than the previously specified one is requested. This has no
51 effect when index mode is disabled.
53 LIBC_COPT_PRINTF_DISABLE_WRITE_INT
54 ----------------------------------
55 When set, this flag disables support for the C Standard "%n" conversion; any
56 "%n" conversion will be treated as invalid. This is set by default to improve
57 security.
59 LIBC_COPT_PRINTF_DISABLE_FLOAT
60 ------------------------------
61 When set, this flag disables support for floating point numbers and all their
62 conversions (%a, %f, %e, %g); any floating point number conversion will be
63 treated as invalid. This reduces code size.
65 LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
66 ----------------------------------
67 When set, this flag disables the nullptr checks in %n and %s.
69 LIBC_COPT_PRINTF_CONV_ATLAS
70 ---------------------------
71 When set, this flag changes the include path for the "converter atlas" which is
72 a header that includes all the files containing the conversion functions. This
73 is not recommended to be set without careful consideration.
75 LIBC_COPT_PRINTF_HEX_LONG_DOUBLE
76 --------------------------------
77 When set, this flag replaces all decimal long double conversions (%Lf, %Le, %Lg)
78 with hexadecimal long double conversions (%La). This will improve performance
79 significantly, but may cause some tests to fail. This has no effect when float
80 conversions are disabled.
82 --------------------------------
83 Float Conversion Internal Flags:
84 --------------------------------
85 The following floating point conversion flags are provided for reference, but
86 are not recommended to be adjusted except by persons familiar with the Printf
87 Ryu Algorithm. Additionally they have no effect when float conversions are
88 disabled.
90 LIBC_COPT_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE
91 -------------------------------------------------
92 When set, the float to string decimal conversion algorithm will use a larger
93 table to accelerate long double conversions. This larger table is around 5MB of 
94 size when compiled. This flag is enabled by default in the CMake.
96 LIBC_COPT_FLOAT_TO_STR_USE_DYADIC_FLOAT(_LD)
97 --------------------------------------------
98 When set, the float to string decimal conversion algorithm will use dyadic
99 floats instead of a table when performing floating point conversions. This
100 results in ~50 digits of accuracy in the result, then zeroes for the remaining
101 values. This may improve performance but may also cause some tests to fail. The
102 flag ending in _LD is the same, but only applies to long double decimal
103 conversions.
105 LIBC_COPT_FLOAT_TO_STR_USE_INT_CALC
106 -----------------------------------
107 When set, the float to string decimal conversion algorithm will use wide
108 integers instead of a table when performing floating point conversions. This
109 gives the same results as the table, but is very slow at the extreme ends of
110 the long double range. If no flags are set this is the default behavior for
111 long double conversions.
113 LIBC_COPT_FLOAT_TO_STR_NO_TABLE
114 -------------------------------
115 When set, the float to string decimal conversion algorithm will not use either
116 the mega table or the normal table for any conversions. Instead it will set
117 algorithmic constants to improve performance when using calculation algorithms.
118 If this flag is set without any calculation algorithm flag set, an error will
119 occur.
121 --------
122 Parsing:
123 --------
125 When printf encounters an invalid conversion specification, the entire
126 conversion specification will be passed literally to the output string.
127 As an example, printf("%Z") would display "%Z".
129 If an index mode conversion is requested for index "n" and there exists a number
130 in [1,n) that does not have a conversion specified in the format string, then
131 the conversion for index "n" is considered invalid.
133 If a non-index mode (also referred to as sequential mode) conversion is
134 specified after an index mode conversion, the next argument will be read but the
135 current index will not be incremented. From this point on, the arguments
136 selected by each conversion may or may not be correct. This is considered
137 dangerously undefined and may change without warning.
139 If a conversion specification is provided an invalid type modifier, that type
140 modifier will be ignored, and the default type for that conversion will be used.
141 In the case of the length modifier "L" and integer conversions, it will be
142 treated as if it was "ll" (lowercase LL). For this purpose the list of integer
143 conversions is d, i, u, o, x, X, n.
145 If a conversion specification ending in % has any options that consume arguments
146 (e.g. "%*.*%") those arguments will be consumed as normal, but their values will
147 be ignored.
149 If a conversion specification ends in a null byte ('\0') then it shall be
150 treated as an invalid conversion followed by a null byte.
152 If a number passed as a min width or precision value is out of range for an int,
153 then it will be treated as the largest or smallest value in the int range
154 (e.g. "%-999999999999.999999999999s" is the same as "%-2147483648.2147483647s").
156 ----------
157 Conversion
158 ----------
159 Any conversion specification that contains a flag or option that it does not
160 have defined behavior for will ignore that flag or option (e.g. %.5c is the same
161 as %c).
163 If a conversion specification ends in %, then it will be treated as if it is
164 "%%", ignoring all options.
166 If a null pointer is passed to a %s conversion specification and null pointer
167 checks are enabled, it will be treated as if the provided string is "null".
169 If a null pointer is passed to a %n conversion specification and null pointer
170 checks are enabled, the conversion will fail and printf will return a negative
171 value.
173 If a null pointer is passed to a %p conversion specification, the string
174 "(nullptr)" will be returned instead of an integer value.
176 The %p conversion will display any non-null pointer as if it was a uintptr value
177 passed to a "%#tx" conversion, with all other options remaining the same as the
178 original conversion.
180 The %p conversion will display a null pointer as if it was the string
181 "(nullptr)" passed to a "%s" conversion, with all other options remaining the
182 same as the original conversion.