brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 4641975 Raw
172 lines · plain
1.. title:: clang-tidy - modernize-use-std-print2 3modernize-use-std-print4=======================5 6Converts calls to ``printf``, ``fprintf``, ``absl::PrintF`` and7``absl::FPrintf`` to equivalent calls to C++23's ``std::print`` or8``std::println`` as appropriate, modifying the format string appropriately.9The replaced and replacement functions can be customised by configuration10options. Each argument that is the result of a call to11``std::string::c_str()`` and ``std::string::data()`` will have that12now-unnecessary call removed in a similar manner to the13:doc:`readability-redundant-string-cstr14<../readability/redundant-string-cstr>` check.15 16In other words, it turns lines like:17 18.. code-block:: c++19 20  fprintf(stderr, "The %s is %3d\n", description.c_str(), value);21 22into:23 24.. code-block:: c++25 26  std::println(stderr, "The {} is {:3}", description, value);27 28If the `ReplacementPrintFunction` or `ReplacementPrintlnFunction` options29are left at or set to their default values then this check is only enabled30with `-std=c++23` or later.31 32Macros starting with ``PRI`` and ``__PRI`` from `<inttypes.h>` are33expanded, escaping is handled and adjacent strings are concatenated to form34a single ``StringLiteral`` before the format string is converted. Use of35any other macros in the format string will cause a warning message to be36emitted and no conversion will be performed. The converted format string37will always be a single string literal.38 39The check doesn't do a bad job, but it's not perfect. In particular:40 41- It assumes that the format string is correct for the arguments. If you42  get any warnings when compiling with `-Wformat` then misbehaviour is43  possible.44 45- At the point that the check runs, the AST contains a single46  ``StringLiteral`` for the format string where escapes have been expanded.47  The check tries to reconstruct escape sequences, they may not be the same48  as they were written (e.g. ``"\x41\x0a"`` will become ``"A\n"`` and49  ``"ab" "cd"`` will become ``"abcd"``.)50 51- It supports field widths, precision, positional arguments, leading zeros,52  leading ``+``, alignment and alternative forms.53 54- Use of any unsupported flags or specifiers will cause the entire55  statement to be left alone and a warning to be emitted. Particular56  unsupported features are:57 58  - The ``%'`` flag for thousands separators.59 60  - The glibc extension ``%m``.61 62- ``printf`` and similar functions return the number of characters printed.63  ``std::print`` does not. This means that any invocations that use the64  return value will not be converted. Unfortunately this currently includes65  explicitly-casting to ``void``. Deficiencies in this check mean that any66  invocations inside ``GCC`` compound statements cannot be converted even67  if the resulting value is not used.68 69If conversion would be incomplete or unsafe then the entire invocation will70be left unchanged.71 72If the call is deemed suitable for conversion then:73 74- ``printf``, ``fprintf``, ``absl::PrintF``, ``absl::FPrintF`` and any75  functions specified by the `PrintfLikeFunctions` option or76  `FprintfLikeFunctions` are replaced with the function specified by the77  `ReplacementPrintlnFunction` option if the format string ends with ``\n``78  or `ReplacementPrintFunction` otherwise.79- the format string is rewritten to use the ``std::formatter`` language. If80  a ``\n`` is found at the end of the format string not preceded by ``r``81  then it is removed and `ReplacementPrintlnFunction` is used rather than82  `ReplacementPrintFunction`.83- any arguments that corresponded to ``%p`` specifiers that84  ``std::formatter`` wouldn't accept are wrapped in a ``static_cast``85  to ``const void *``.86- any arguments that corresponded to ``%s`` specifiers where the argument87  is of ``signed char`` or ``unsigned char`` type are wrapped in a88  ``reinterpret_cast<const char *>``.89- any arguments where the format string and the parameter differ in90  signedness will be wrapped in an appropriate ``static_cast`` if `StrictMode`91  is enabled.92- any arguments that end in a call to ``std::string::c_str()`` or93  ``std::string::data()`` will have that call removed.94 95Options96-------97 98.. option:: StrictMode99 100   When `true`, the check will add casts when converting from variadic101   functions like ``printf`` and printing signed or unsigned integer types102   (including fixed-width integer types from ``<cstdint>``, ``ptrdiff_t``,103   ``size_t`` and ``ssize_t``) as the opposite signedness to ensure that104   the output matches that of ``printf``. This does not apply when105   converting from non-variadic functions such as ``absl::PrintF`` and106   ``fmt::printf``. For example, with `StrictMode` enabled:107 108  .. code-block:: c++109 110    int i = -42;111    unsigned int u = 0xffffffff;112    printf("%u %d\n", i, u);113 114  would be converted to:115 116  .. code-block:: c++117 118    std::print("{} {}\n", static_cast<unsigned int>(i), static_cast<int>(u));119 120  to ensure that the output will continue to be the unsigned representation121  of `-42` and the signed representation of `0xffffffff` (often122  `4294967254` and `-1` respectively.) When `false` (which is the default),123  these casts will not be added which may cause a change in the output.124 125.. option:: PrintfLikeFunctions126 127   A semicolon-separated list of regular expressions matching the128   (fully qualified) names of functions to replace, with the requirement129   that the first parameter contains the printf-style format string and the130   arguments to be formatted follow immediately afterwards. Qualified member131   function names are supported, but the replacement function name must be132   unqualified. If neither this option nor `FprintfLikeFunctions` are set then133   the default value is `printf; absl::PrintF`, otherwise it is the empty134   string.135 136 137.. option:: FprintfLikeFunctions138 139   A semicolon-separated list of regular expressions matching the140   (fully qualified) names of functions to replace, with the requirement141   that the first parameter is retained, the second parameter contains the142   printf-style format string and the arguments to be formatted follow143   immediately afterwards. Qualified member function names are supported,144   but the replacement function name must be unqualified. If neither this145   option nor `PrintfLikeFunctions` are set then the default value is146   `fprintf;absl::FPrintF`, otherwise it is the empty string.147 148 149.. option:: ReplacementPrintFunction150 151   The function that will be used to replace ``printf``, ``fprintf`` etc.152   during conversion rather than the default ``std::print`` when the153   originalformat string does not end with ``\n``. It is expected that the154   function provides an interface that is compatible with ``std::print``. A155   suitable candidate would be ``fmt::print``.156 157.. option:: ReplacementPrintlnFunction158 159   The function that will be used to replace ``printf``, ``fprintf`` etc.160   during conversion rather than the default ``std::println`` when the161   original format string ends with ``\n``. It is expected that the162   function provides an interface that is compatible with ``std::println``.163   A suitable candidate would be ``fmt::println``.164 165.. option:: PrintHeader166 167   The header that must be included for the declaration of168   `ReplacementPrintFunction` so that a ``#include`` directive can be169   added if required. If `ReplacementPrintFunction` is ``std::print``170   then this option will default to ``<print>``, otherwise this option will171   default to nothing and no ``#include`` directive will be added.172