Date: Sat, 26 Jul 2025 12:47:19 +0200
Still it is not clear, why you want to introduce badptr in addition to nullptr. If you say nullptr being 0 is too obvious, then as you mentioned, you can compile differently. And you would have to care for library interfaces and the operating system.
It seems even C, allows the pointer representation of NULL being not 0 and this other value being set, when assigning a pointer with 0.
Code actively has to set pointers to badptr at some point. So you can set to an invalid memory page. There is no need for further standardization, you can just do that.
-----Ursprüngliche Nachricht-----
Von:Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Gesendet:Sa 26.07.2025 12:44
Betreff:Re: [std-proposals] Standardising 0xdeadbeef for pointers
An:std-proposals <std-proposals_at_[hidden]>;
CC:Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>;
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__"
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-07-26 10:57:10