Date: Thu, 3 Sep 2026 18:17:40 +0200
This idea seems unimplementable to me because it's not observable whether
you new'd an object. You can use the address as a sign of whether something
is on the heap or stack, but I'm not sure how portable that is. It also
breaks down when heap elision optimization takes place, and I wouldn't want
a feature that inhibits it.
As things stand, if the compiler can prove that an object is allocated and
deallocated within a certain scope, it can skip that part and just put it
on the stack.
And if you want to insist on new, you can already do that by making the
constructors private and only allowing static member functions to create
instances.
On Thu, Sep 3, 2026, 17:54 Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> 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
>
you new'd an object. You can use the address as a sign of whether something
is on the heap or stack, but I'm not sure how portable that is. It also
breaks down when heap elision optimization takes place, and I wouldn't want
a feature that inhibits it.
As things stand, if the compiler can prove that an object is allocated and
deallocated within a certain scope, it can skip that part and just put it
on the stack.
And if you want to insist on new, you can already do that by making the
constructors private and only allowing static member functions to create
instances.
On Thu, Sep 3, 2026, 17:54 Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> 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:17:58
