Clang 19 has recently been released. It includes my new modernize-use-std-format check and fixes a bug in the modernize-use-std-print check that I added in Clang 17. (I also fixed another bug in the intervening Clang 18 release.)
The new modernise-use-std-format check by default turns
calls to absl::StrFormat
into calls to std::format
.
For example,
it turns:
return absl::StrFormat("The %s is %d", description.c_str(), value);
into
return std::format("The {} is {}", description, value);
The full documentation for the check is available on the clang-tidy web site.
Although the default behaviour of the check is to replace calls to
absl::StrFormat
, many codebases have their own “wrap snprintf
to return a std::string
” function. Ours was called
strprintf
.
Given a file named example.cpp
containing:
#include <string>
extern std::string strprintf(const char *format, ...);
std::string format_row(int quantity, const std::string &name, double mass, const std::string &description)
{
return strprintf("| %3d | %10s | %6.3fkg | %-30s |\n", quantity, name.c_str(), mass, description.c_str());
}
int main()
{
(format_row(4, "carrots", 0.25, "Long orange things").c_str());
puts(format_row(9, "sprouts", 0.1, "Roundish green things").c_str());
puts}
then running
clang-tidy '-checks=-*,modernize-use-std-format' \
-config="{CheckOptions: { modernize-use-std-format.StrFormatLikeFunctions: '::strprintf;' }}" \
-fix example.cpp -- -std=c++20
will result in the file being rewritten to:
#include <format>
#include <string> 'format' file not found [pp_file_not_found]
extern std::string strprintf(const char *format, ...);
std::string format_row(int quantity, const std::string &name, double mass, const std::string &description)
{
return std::format("| {:3} | {:>10} | {:6.3f}kg | {:30} |\n", quantity, name, mass, description);
}
int main()
{
(format_row(4, "carrots", 0.25, "Long orange things").c_str());
puts(format_row(9, "sprouts", 0.1, "Roundish green things").c_str());
puts}
The check has done several things:
- The
<format>
header is now included. (The declaration ofstrprintf
has not been removed since it may still be used in ways that could not be converted.) - The
strprintf
call has been replaced withstd::format
. - The format string has been rewritten to use the new C++ format language.
- The now-unnecessary calls to
std::string::c_str()
forname
anddescription
have been removed.
If you aren’t able to use C++20 yet then the check can be told to use
fmt::format
from the {fmt}
library instead with something like:
clang-tidy '-checks=-*,modernize-use-std-format' \
-config="{CheckOptions: { \
modernize-use-std-format.StrFormatLikeFunctions: '::strprintf;', \
modernize-use-std-format.ReplacementFormatFunction: 'fmt::format', \
modernize-use-std-format.FormatHeader: '<fmt/core.h>' }}" \
-fix example.cpp
You can play with the modernize-use-std-format and modernize-use-std-print checks using the excellent Compiler Explorer.
Thanks to everyone who reviewed and made suggestions for the new check and bug fixes. I have several further improvements to these checks in development that I hope will land in time for Clang 20.
No comments:
Post a Comment