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).