isocpp / isocpp/CppCoreGuidelines
How do we handle "immortal" pointers that are reachable for entire lifetime of an app?
@hsutter is already working on this.
Since Nov 27, 2017.
- Dominant language
- CSS
- Stars
- 45.3k
- Forks
- 5.6k
- PR merge metrics
- No merged PRs in 30d
Description
The "Google C++ Style Guide" forbids variables of static storage duration and Titus Winters in
"CppCon 2017: Titus Winters “Hands-On With Abseil" ( https://www.youtube.com/watch?v=xu7q8dGvuwk ) gave some of the engineering reasons behind this rules which seems to be entirely reasonable.
In short , at the global namespace, Google's prefers this
#include <iostream>
const std::string& str() {
static std::string* s = new std::string("Hello");
return *s;
}
main() {
std::cout << str();
}
over
#include <iostream>
const std::string str("Hello");
main() {
std::cout << str;
}
as new std::string("Hello") is intended to be reachable for the entire lifetime of the app and thus it's not strictly necessary to run std::string's dtor and deallocate memory as the OS will eventually recover the memory when process finally terminates. In fact it helps if new std::string("Hello") is never deleted as we can avoid the complication of coordinating its destruction order with respect to other static variables/threads that may refer to it when a program exits main.
In this situation, I assume static gsl::owner<std::string*> s = new std::string("Hello"); is not appropriate as the code checking tools should warn that a delete s is missing?
Instead, does it makes sense to have a gsl::immortal to indicate that the object is intentionally never deleted? e.g.
const std::string& str() {
static gsl::immortal<std::string*> s = new std::string("Hello");
return *s;
}
In addition, we could complement gsl::immortal with gsl::make_immortal(...) as this give us :
- Ability to allocate from a mem pool to reduce possible memory fragmentation.
- Convenient opportunity to inform a mem leak detector that the mem alloc is intentionally not matched by a dealloc.
This would be especially helpful for the light-weight mem leak detector that's built into MSVC's debug CRT.
e.g.
namespace gsl {
template<typename T, typename Args>
gsl::immortal<T> make_immortal(Args&&... a) {
T p;
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
_CrtSetDbgFlag(flag & ~_CRTDBG_ALLOC_MEM_DF);
try {
p = new T(std::forward<Args>(a)...);
}
catch(...) {
_CrtSetDbgFlag(flag);
throw;
}
_CrtSetDbgFlag(flag);
return p;
}
}
const std::string& str() {
static auto s = gsl::make_immortal<std::string*>("Hello");
return *s;
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.