Date: Thu, 3 Sep 2026 16:36:07 +0000
How would you distinguish this from malloc, or arenas, or even arrays?
This is not only not implementable, I wouldn't want this to be implementable, it also uses a style of C++ we don't really use much anymore.
What would this even be for?
________________________________
From: Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf of Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Sent: Thursday, September 3, 2026 5:54:51 PM
To: std-proposals <std-proposals_at_[hidden]>
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Subject: [std-proposals] std::came_from_new [[must_new]]
Some libraries have classes that you must create objects of with
'new', because later they're destroyed by an object management system
which uses 'delete'.
An example of this is wxWindow in the wxWidgets library. You can do this:
auto *p = new wxButton();
main_window.AddWidget( p );
but you can't do this:
wxButton b;
main_window.AddWidget( &b );
The problem with the latter is that it will later call 'delete' on a
variable that wasn't new'd.
So I was thinking, would it be helpful if C++29 had the following?
class wxWindow {
public:
wxWindow(void)
{
assert( std::came_from_new(this) );
}
};
Or perhaps even a more generic function like "std::origin" which would return:
1 - static global
2 - static thread-local
3 - stack
4 - heap
On Linux I think this would be coded something along the lines of:
bool came_from_heap(const void *p)
{
if (p == nullptr)
{
return false;
}
const std::uintptr_t address = reinterpret_cast<std::uintptr_t>(p);
FILE *file = std::fopen("/proc/self/maps", "r");
if (file == nullptr) return false;
char line[512];
while (std::fgets(line, sizeof(line), file) != nullptr)
{
std::uintptr_t begin;
std::uintptr_t end;
char permissions[5];
char pathname[256];
const int fields = std::sscanf(
line,
"%lx-%lx %4s %*s %*s %*s %255[^\n]",
&begin,
&end,
permissions,
pathname);
if (fields == 4 &&
address >= begin &&
address < end &&
std::strcmp(pathname, "[heap]") == 0)
{
std::fclose(file);
return true;
}
}
std::fclose(file);
return false;
}
An alternative to this would be to force a compile-time error if you
don't use new to create an object:
class wxWindow {
public:
[[must_be_new]] wxWindow(void)
{
// code goes here
}
};
This is not only not implementable, I wouldn't want this to be implementable, it also uses a style of C++ we don't really use much anymore.
What would this even be for?
________________________________
From: Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf of Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Sent: Thursday, September 3, 2026 5:54:51 PM
To: std-proposals <std-proposals_at_[hidden]>
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Subject: [std-proposals] std::came_from_new [[must_new]]
Some libraries have classes that you must create objects of with
'new', because later they're destroyed by an object management system
which uses 'delete'.
An example of this is wxWindow in the wxWidgets library. You can do this:
auto *p = new wxButton();
main_window.AddWidget( p );
but you can't do this:
wxButton b;
main_window.AddWidget( &b );
The problem with the latter is that it will later call 'delete' on a
variable that wasn't new'd.
So I was thinking, would it be helpful if C++29 had the following?
class wxWindow {
public:
wxWindow(void)
{
assert( std::came_from_new(this) );
}
};
Or perhaps even a more generic function like "std::origin" which would return:
1 - static global
2 - static thread-local
3 - stack
4 - heap
On Linux I think this would be coded something along the lines of:
bool came_from_heap(const void *p)
{
if (p == nullptr)
{
return false;
}
const std::uintptr_t address = reinterpret_cast<std::uintptr_t>(p);
FILE *file = std::fopen("/proc/self/maps", "r");
if (file == nullptr) return false;
char line[512];
while (std::fgets(line, sizeof(line), file) != nullptr)
{
std::uintptr_t begin;
std::uintptr_t end;
char permissions[5];
char pathname[256];
const int fields = std::sscanf(
line,
"%lx-%lx %4s %*s %*s %*s %255[^\n]",
&begin,
&end,
permissions,
pathname);
if (fields == 4 &&
address >= begin &&
address < end &&
std::strcmp(pathname, "[heap]") == 0)
{
std::fclose(file);
return true;
}
}
std::fclose(file);
return false;
}
An alternative to this would be to force a compile-time error if you
don't use new to create an object:
class wxWindow {
public:
[[must_be_new]] wxWindow(void)
{
// code goes here
}
};
-- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2026-09-03 16:36:14
