Path: csiph.com!weretis.net!feeder9.news.weretis.net!news.quux.org!eternal-september.org!feeder2.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c++ Subject: Re: "Safe C++ is A new Proposal to Make C++ Memory-Safe" Date: Mon, 04 Nov 2024 06:59:14 -0800 Organization: A noiseless patient Spider Lines: 84 Message-ID: <86cyjbt58d.fsf@linuxsc.com> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Mon, 04 Nov 2024 15:59:18 +0100 (CET) Injection-Info: dont-email.me; posting-host="f359696380662fa6462481cb0fc8fe02"; logging-data="1056401"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+emhrDImXbBip2Uxh5ITToQCMfXhHH9dY=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:3xjWv0gpmXsFsGqKH0oGH4CpSNo= sha1:mIZXLcTmcON0ST3FzaCAAmhOVNs= Xref: csiph.com comp.lang.c++:120835 jseigh writes: [...] > You create a new nullable attribute for pointers. That > would make the pointer behave like void* instead of T*. > You could move, copy, and compare, but you could not > dereference them. If you wanted to dereference them > you would have to apply a special not_null unary predicate > to them. What makes it special is the boolean result > is only valid inside a conditional expression. It's > not copyable or referencable. You could have 1 or > more of these in a conditional expression along with > ordinary predicates with the restriction that the > expression has to be formed such that if any of the > not_null terms are false, the expression has to > evaluate as false. > > The other thing that makes not_null is that inside > if the conditional statements true blocks, the > nullable pointer gets it T* properties back, so > you can dereference it, but again only in the > true blocks. So for example > > nullable T* p = &something; > > T p2 = *p; // invalid, compiler thinks you are trying > // do dereference void* > > not_null(p); // invalid, not inside conditional expression > > if (not_null(p) > p2 = *p; // valid > else > p2 = *p; // invalid > > > Traversing a linked list would look like > > T* p = head; > while (not_null(p)) { > ... > p = p->next; // valid, inside while true block > } > > not_null would look like > __predicate_bool not_null(T *&) > It would make a const copy of T*, test that, > cast to T*, use it for the true block. > > So no NPEs possible for pointer with this > attribute. A few comments. An "attribute" should be placed like a qualifier, next to the pointer, rather than before the type specifier. The sense of the attribute should be "never null" rather than "nullable". Ordinary pointers are nullable; what is needed is a way to indicate that a particular pointer (either a variable or the return value of a function) will never be null. I expect there are implications for pointers to never-null pointers, but I haven't tried to work out what they need to be. Example: 'T *nevernull *p;'. What are the rules for assigning to p? Ordinary pointers can (sometimes) be determined to be non-null using data flow analysis (like what you say in the followup post for the linked list example). There is no need for not_null(). If we see if(p){ ... } or while(p){ ... } we know that p will not be null inside the controlled statement (subject to change if there is an assignment to p, per the data flow remark above).