From 9d770560aef97505e20cb26780ca8d3ed1e2ffe9 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:27:50 +0100 Subject: [PATCH 1/6] avoid temporary object creations with macro insertions in `simplecpp::preprocess()` --- simplecpp.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 7afc17ab..0c6c7e77 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -3367,7 +3367,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL const std::string rhs(eq==std::string::npos ? std::string("1") : macrostr.substr(eq+1)); try { const Macro macro(lhs, rhs, dummy); - macros.insert(std::pair(macro.name(), macro)); + macros.emplace(macro.name(), macro); } catch (const std::runtime_error& e) { if (outputList) { simplecpp::Output err{ @@ -3384,22 +3384,22 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL const bool strictAnsiUndefined = dui.undefined.find("__STRICT_ANSI__") != dui.undefined.cend(); if (!isGnu(dui) && !strictAnsiDefined && !strictAnsiUndefined) - macros.insert(std::pair("__STRICT_ANSI__", Macro("__STRICT_ANSI__", "1", dummy))); + macros.emplace("__STRICT_ANSI__", Macro("__STRICT_ANSI__", "1", dummy)); - macros.insert(std::make_pair("__FILE__", Macro("__FILE__", "__FILE__", dummy))); - macros.insert(std::make_pair("__LINE__", Macro("__LINE__", "__LINE__", dummy))); - macros.insert(std::make_pair("__COUNTER__", Macro("__COUNTER__", "__COUNTER__", dummy))); + macros.emplace("__FILE__", Macro("__FILE__", "__FILE__", dummy)); + macros.emplace("__LINE__", Macro("__LINE__", "__LINE__", dummy)); + macros.emplace("__COUNTER__", Macro("__COUNTER__", "__COUNTER__", dummy)); struct tm ltime {}; getLocaltime(ltime); - macros.insert(std::make_pair("__DATE__", Macro("__DATE__", getDateDefine(<ime), dummy))); - macros.insert(std::make_pair("__TIME__", Macro("__TIME__", getTimeDefine(<ime), dummy))); + macros.emplace("__DATE__", Macro("__DATE__", getDateDefine(<ime), dummy)); + macros.emplace("__TIME__", Macro("__TIME__", getTimeDefine(<ime), dummy)); if (!dui.std.empty()) { const cstd_t c_std = simplecpp::getCStd(dui.std); if (c_std != CUnknown) { const std::string std_def = simplecpp::getCStdString(c_std); if (!std_def.empty()) - macros.insert(std::make_pair("__STDC_VERSION__", Macro("__STDC_VERSION__", std_def, dummy))); + macros.emplace("__STDC_VERSION__", Macro("__STDC_VERSION__", std_def, dummy)); } else { const cppstd_t cpp_std = simplecpp::getCppStd(dui.std); if (cpp_std == CPPUnknown) { @@ -3416,7 +3416,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL } const std::string std_def = simplecpp::getCppStdString(cpp_std); if (!std_def.empty()) - macros.insert(std::make_pair("__cplusplus", Macro("__cplusplus", std_def, dummy))); + macros.emplace("__cplusplus", Macro("__cplusplus", std_def, dummy)); } } @@ -3503,7 +3503,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL if (dui.undefined.find(macro.name()) == dui.undefined.end()) { const MacroMap::iterator it = macros.find(macro.name()); if (it == macros.end()) - macros.insert(std::pair(macro.name(), macro)); + macros.emplace(macro.name(), macro); else it->second = macro; } From 383e968a89fd84ee32ed72cb3217171c0198305d Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:38:50 +0100 Subject: [PATCH 2/6] create `Macro` objects in-place --- simplecpp.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 0c6c7e77..24b92bf6 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -47,6 +47,7 @@ #ifdef SIMPLECPP_WINDOWS # include #endif +#include #include #include #include @@ -3384,22 +3385,22 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL const bool strictAnsiUndefined = dui.undefined.find("__STRICT_ANSI__") != dui.undefined.cend(); if (!isGnu(dui) && !strictAnsiDefined && !strictAnsiUndefined) - macros.emplace("__STRICT_ANSI__", Macro("__STRICT_ANSI__", "1", dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__STRICT_ANSI__"), std::forward_as_tuple("__STRICT_ANSI__", "1", dummy)); - macros.emplace("__FILE__", Macro("__FILE__", "__FILE__", dummy)); - macros.emplace("__LINE__", Macro("__LINE__", "__LINE__", dummy)); - macros.emplace("__COUNTER__", Macro("__COUNTER__", "__COUNTER__", dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__FILE__"), std::forward_as_tuple("__FILE__", "__FILE__", dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__LINE__"), std::forward_as_tuple("__LINE__", "__LINE__", dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__COUNTER__"), std::forward_as_tuple("__COUNTER__", "__COUNTER__", dummy)); struct tm ltime {}; getLocaltime(ltime); - macros.emplace("__DATE__", Macro("__DATE__", getDateDefine(<ime), dummy)); - macros.emplace("__TIME__", Macro("__TIME__", getTimeDefine(<ime), dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__DATE__"), std::forward_as_tuple("__DATE__", getDateDefine(<ime), dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__TIME__"), std::forward_as_tuple("__TIME__", getTimeDefine(<ime), dummy)); if (!dui.std.empty()) { const cstd_t c_std = simplecpp::getCStd(dui.std); if (c_std != CUnknown) { const std::string std_def = simplecpp::getCStdString(c_std); if (!std_def.empty()) - macros.emplace("__STDC_VERSION__", Macro("__STDC_VERSION__", std_def, dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__STDC_VERSION__"), std::forward_as_tuple("__STDC_VERSION__", std_def, dummy)); } else { const cppstd_t cpp_std = simplecpp::getCppStd(dui.std); if (cpp_std == CPPUnknown) { @@ -3416,7 +3417,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL } const std::string std_def = simplecpp::getCppStdString(cpp_std); if (!std_def.empty()) - macros.emplace("__cplusplus", Macro("__cplusplus", std_def, dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__cplusplus"), std::forward_as_tuple("__cplusplus", std_def, dummy)); } } From c3479ab986dc348b63cd41cec21d633ebd1acdad Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:45:12 +0100 Subject: [PATCH 3/6] changed `simplecpp::Macro::tokenListDefine` to a shared pointer --- simplecpp.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 24b92bf6..bd83f7fd 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -1499,12 +1500,12 @@ namespace simplecpp { class Macro { public: - explicit Macro(std::vector &f) : nameTokDef(nullptr), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(f), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} + explicit Macro(std::vector &f) : nameTokDef(nullptr), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(new TokenList(f)), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} /** * @throws std::runtime_error thrown on bad macro syntax */ - Macro(const Token *tok, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(f), valueDefinedInCode_(true) { + Macro(const Token *tok, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(true) { if (sameline(tok->previousSkipComments(), tok)) throw std::runtime_error("bad macro syntax"); if (tok->op != '#') @@ -1523,15 +1524,15 @@ namespace simplecpp { /** * @throws std::runtime_error thrown on bad macro syntax */ - Macro(const std::string &name, const std::string &value, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(f), valueDefinedInCode_(false) { + Macro(const std::string &name, const std::string &value, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(false) { const std::string def(name + ' ' + value); StdCharBufStream stream(reinterpret_cast(def.data()), def.size()); - tokenListDefine.readfile(stream); - if (!parseDefine(tokenListDefine.cfront())) + tokenListDefine->readfile(stream); + if (!parseDefine(tokenListDefine->cfront())) throw std::runtime_error("bad macro syntax. macroname=" + name + " value=" + value); } - Macro(const Macro &other) : nameTokDef(nullptr), files(other.files), tokenListDefine(other.files), valueDefinedInCode_(other.valueDefinedInCode_) { + Macro(const Macro &other) : nameTokDef(nullptr), files(other.files), tokenListDefine(other.tokenListDefine), valueDefinedInCode_(other.valueDefinedInCode_) { // TODO: remove the try-catch - see #537 // avoid bugprone-exception-escape clang-tidy warning try { @@ -1549,12 +1550,12 @@ namespace simplecpp { if (this != &other) { files = other.files; valueDefinedInCode_ = other.valueDefinedInCode_; - if (other.tokenListDefine.empty()) { + if (other.tokenListDefine->empty()) { parseDefine(other.nameTokDef); } else { tokenListDefine = other.tokenListDefine; - parseDefine(tokenListDefine.cfront()); + parseDefine(tokenListDefine->cfront()); } usageList = other.usageList; } @@ -2424,7 +2425,7 @@ namespace simplecpp { std::vector &files; /** this is used for -D where the definition is not seen anywhere in code */ - TokenList tokenListDefine; + std::shared_ptr tokenListDefine; /** usage of this macro */ mutable std::list usageList; From 82eff4f31d4159737bde706bd2887d8b9ca8aa96 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:50:16 +0100 Subject: [PATCH 4/6] avoid redundant initialization of `simplecpp::Macro::nameTokDef` --- simplecpp.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index bd83f7fd..085fecb4 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1500,12 +1500,12 @@ namespace simplecpp { class Macro { public: - explicit Macro(std::vector &f) : nameTokDef(nullptr), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(new TokenList(f)), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} + explicit Macro(std::vector &f) : valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(new TokenList(f)), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} /** * @throws std::runtime_error thrown on bad macro syntax */ - Macro(const Token *tok, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(true) { + Macro(const Token *tok, std::vector &f) : files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(true) { if (sameline(tok->previousSkipComments(), tok)) throw std::runtime_error("bad macro syntax"); if (tok->op != '#') @@ -1524,7 +1524,7 @@ namespace simplecpp { /** * @throws std::runtime_error thrown on bad macro syntax */ - Macro(const std::string &name, const std::string &value, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(false) { + Macro(const std::string &name, const std::string &value, std::vector &f) : files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(false) { const std::string def(name + ' ' + value); StdCharBufStream stream(reinterpret_cast(def.data()), def.size()); tokenListDefine->readfile(stream); @@ -1532,7 +1532,7 @@ namespace simplecpp { throw std::runtime_error("bad macro syntax. macroname=" + name + " value=" + value); } - Macro(const Macro &other) : nameTokDef(nullptr), files(other.files), tokenListDefine(other.tokenListDefine), valueDefinedInCode_(other.valueDefinedInCode_) { + Macro(const Macro &other) : files(other.files), tokenListDefine(other.tokenListDefine), valueDefinedInCode_(other.valueDefinedInCode_) { // TODO: remove the try-catch - see #537 // avoid bugprone-exception-escape clang-tidy warning try { @@ -2410,7 +2410,7 @@ namespace simplecpp { } /** name token in definition */ - const Token *nameTokDef; + const Token *nameTokDef{}; /** arguments for macro */ std::vector args; From 492fe294d9cccf51336eb167a46e7769c9b90ce9 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:52:57 +0100 Subject: [PATCH 5/6] avoid duplicated assignment of `simplecpp::Macro::tokenListDefine` --- simplecpp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 085fecb4..82d68ff5 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1532,7 +1532,7 @@ namespace simplecpp { throw std::runtime_error("bad macro syntax. macroname=" + name + " value=" + value); } - Macro(const Macro &other) : files(other.files), tokenListDefine(other.tokenListDefine), valueDefinedInCode_(other.valueDefinedInCode_) { + Macro(const Macro &other) : files(other.files), valueDefinedInCode_(other.valueDefinedInCode_) { // TODO: remove the try-catch - see #537 // avoid bugprone-exception-escape clang-tidy warning try { @@ -1550,11 +1550,11 @@ namespace simplecpp { if (this != &other) { files = other.files; valueDefinedInCode_ = other.valueDefinedInCode_; - if (other.tokenListDefine->empty()) { + tokenListDefine = other.tokenListDefine; + if (!tokenListDefine || tokenListDefine->empty()) { parseDefine(other.nameTokDef); } else { - tokenListDefine = other.tokenListDefine; parseDefine(tokenListDefine->cfront()); } usageList = other.usageList; From 90037ae80d18fa8eccc04ee4679d0f72f22d0934 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:56:05 +0100 Subject: [PATCH 6/6] removed unnecessary creation of `simplecpp::Macro::tokenListDefine` --- simplecpp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 82d68ff5..534f630e 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1500,12 +1500,12 @@ namespace simplecpp { class Macro { public: - explicit Macro(std::vector &f) : valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(new TokenList(f)), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} + explicit Macro(std::vector &f) : valueToken(nullptr), endToken(nullptr), files(f), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} /** * @throws std::runtime_error thrown on bad macro syntax */ - Macro(const Token *tok, std::vector &f) : files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(true) { + Macro(const Token *tok, std::vector &f) : files(f), valueDefinedInCode_(true) { if (sameline(tok->previousSkipComments(), tok)) throw std::runtime_error("bad macro syntax"); if (tok->op != '#')