C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Standardising 0xdeadbeef for pointers

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sat, 26 Jul 2025 11:44:05 +0100
On Friday, July 25, 2025, Tiago Freire wrote:

I don't know about you, but intentionally segfaulting is not something I
> want in my application.
>


I want the Release build to run perfectly and to get a glowing review,
without any segfaults.

However, as a step toward achieving this, I want the Debug build to halt
and clearly explain to me what went wrong. I have coined this "The Halting
Solution".

I'll give you an example. I wrote a free open-source program called Dynamo
and released the first version about 17 years ago. It pretty much ran
perfectly, but I noticed sometimes that the network MAC address in the list
view on screen would sometimes have garbage characters. This was before C++
11, and so we used to extend the lifetime of a return value as follows:

    MyClass const &obj = FuncReturnsByValue();

Nowadays with C++ 11, we just write:

    MyClass obj = FuncReturnsByValue();

Well, it turned out that FuncReturnsByValue only returned by value under
MS-Windows, and it actually returned a const reference under Linux and
Apple -- I remember enlisting the guys on comp.lang.c++ to help me get to
the bottom of it, and they pointed me to this excerpt from a 3rd party
header file:

    #ifdef BOOST_WINDOWS_API
        const std::string string() const { return string(codecvt()); }
    #else // BOOST_POSIX_API
        // string_type is std::string, so there is no conversion
    const std::string& string() const { return m_pathname; }

So when I took that return value and bound it to an Lvalue const reference,
its lifetime got extended on MS-Windows, but not on Linux and Apple. On
Linux and Apple, the referred object sometimes got destroyed before the GUI
thread displayed it on screen, giving me garbage characters.

I would have preferred if the Debug build halted immediately. I think the
GNU Address Sanitizer nowadays would catch the above bug.

I want my Release build to hobble on even when something goes wrong, and I
even catch and discard exceptions in some destructors to achieve this in
the Release build (i.e. I don't want std::terminate getting called). I've
edited Arthur O'Dwyer's Auto macro to catch exceptions in the destructor if
NDEBUG is defined, like this:

https://github.com/healytpk/paperkernelcxx/blob/main/main_program/Auto.h

It's very rare that I call std::abort in any program . . . and actually
I'll call std::_Exit instead if I think it's time to die as it's the
closest thing to:

    mov rax, 60
    mov rdi, 0
    syscall

So 0xdeadbeef probably doesn't have any place in a Release build, but it
certainly helps when debugging.

Since all bits zero is already being used for nullptr, maybe all bits one
would be good for badptr. I know Oliver linked us to a page that had
computers with not-all-bits-zero nullptr's but they were all dinosaurs. The
reason why it makes perfect sense for nullptr to be all-bits-zero is that
every CPU instruction set has optimised instructions to check if a
register's value is zero. The opcode + operand to compare a register value
with 0xFFFFFFFFFFFFFFFF is a few more bytes. Plus the 'jump' instructions
have optimised forms such as 'jump if zero' and 'jump if non-zero' which
are perfect for branching on nullptr.

We've already mandated that the number system must be Two's. We're
considering mandating that CHAR_BIT must be 8, so maybe also mandate that
nullptr is all bits zero -- which opens the door to make badptr all bits
one.

If the compiler and debugger notice the accessing of memory address
0xFFFFFFFFFFFFFFFF, then maybe they can suspend the process and tell the
user:

    "Badptr dereferenced in __FUNCTION__, possibly after having been set to
badptr in __OTHER_FUNCTION__"

Received on 2025-07-26 10:44:09