Use `cmStrCat` to construct variable names
There are lots of places in the code that can benefit from cmStrCat
.
According to #19555 (comment 606317), there are 783 uses of std::ostringstream
that could potentially be refactored to use cmStrCat
. However, those uses are mostly to generate error messages. There is no big benefit on the performance of a typical execution. So, this should not be high priority.
A bigger benefit is the refactoring of variable name construction. CMake internally constructs variable names like CMAKE_<LANG>_FLAGS_<CONFIG>
, in order to perform a lookup of the value of that variable.
This is typically written in the following style at the moment:
std::string flagsVar = "CMAKE_";
flagsVar += lang;
flagsVar += "_FLAGS_";
flagsVar += config;
std::string const& flags = this->Makefile->GetSafeDefinition(flagsVar);
With cmStrCat
, it can be rewritten as:
std::string const& flags = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_FLAGS_", config));
This is
- easier to read (because it is shorter),
- more robust (less side effects, there is no mutable variable
flagsVar
), and - faster (because
cmStrCat
creates the result string with the right length from the beginning).
Because those variable names always have an uppercase letter and an underscore before a placeholder, we can find all the places where argument names are constructed the old way by searching for the regular expression: [A-Z]_";
.
We can list all those places with:
grep --recursive '[A-Z]_";' Source/
!3671 (merged) is an example for such a refactoring.