public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Alejandro Colomar (man-pages)" <alx.manpages@gmail.com>
To: Dmitri Gribenko <gribozavr@gmail.com>
Cc: Joseph Myers <joseph@codesourcery.com>,
	gcc@gcc.gnu.org, cfe-dev <cfe-dev@lists.llvm.org>
Subject: Re: [cfe-dev] ISO C3X proposal: nonnull qualifier
Date: Wed, 1 Dec 2021 23:24:33 +0100	[thread overview]
Message-ID: <f6f6a77c-400f-3fa8-3e05-ac476b26b416@gmail.com> (raw)
In-Reply-To: <CA+Y5xYcKfDu-jiRDrJTqAKq+QrP47ymnMEu669CJDCxp=yt2bg@mail.gmail.com>

Hi Dmitry,

On 11/23/21 13:45, Dmitri Gribenko wrote:
>>
>> Let's imagine a scenario where C3X specifies that non-qualified pointers
>> are nonnull.  And there's only a qualifier, _Nullable, to allow NULL.
>> Asigning _Nullable to nonnull would issue a diagnostic.
> 
> I think C3X specifying that non-qualified pointers are nonnnull would
> be a showstopper, I don't think it is likely to happen given how the
> users and the committee value backward compatibility that C has
> offered throughout the decades.

Agreed.  I even found some cases where it would cause previously-correct
code to misbehave, so changing normal pointers to mean nonnull pointers
is not possible at this point.  Compilers may allow that with pragmas
anyway.

> 
> If I were to speculate what would happen if C3X did flip the default,
> I think it would be treated by the community as a language fork.

Yes

> Pre-C3X headers won't work correctly when included in C3X programs,
> making incremental adoption of C3X syntax, as it was intended to be
> used, impossible. Projects would likely invent a NULLABLE macro, which
> would expand to _Nullable in C3X and nothing in earlier versions, to
> enable an incremental transition.
> 
> That's why Clang introduced the pragma, enabling new rules to be
> adopted incrementally.

Let's avoid forking C :)

> 
>> Also, do you have any experience in avoiding to diagnose a _Nullable to
>> nonnull assignment _after_ explicitly comparing to NULL?  I.e., allow
>> the following:
>>
>> int *_Nullable p;
>> int *q;
>>
>> if (!p)
>>         q = p;
> 
> Internally at Google we have a checker based on the dataflow analysis
> framework (https://lists.llvm.org/pipermail/cfe-dev/2021-October/069098.html)
> that diagnoses usages of std::optional<T>::value() not guarded by
> has_value(). We are planning to upstream it after we finish
> upstreaming the dataflow framework itself. Ensuring guarded usage of
> std::optional<T>::value() is very similar to diagnosing dereferences
> of nullable pointers. I think a lot of the experience is transferable.
> However, we haven't attempted to implement a pointer nullability check
> yet, so I don't yet understand all corner cases that arise in real
> world software.
> 
> However, fundamentally, there are a few questions that you need to answer:
> 
> - does _Nullable create a distinct type or not? It is extremely
> important when you consider C++.

Let's talk about _Nonnull, which is more likely to be added.

I would say no.  Neither const or restrict create a new type, but a
qualified version of a type.  _Nonnull has a behavior somewhat in
between restrict and const.

> 
> - do you want nullability-related diagnostics to be mandatory, or
> optional? For example, a compiler is not required to issue a
> diagnostic about a program that violates the constraints of
> `restrict`.

I think this should be similar to const, so a mandatory warning would be
better.  But still I have doubts, because this is much more complex to
diagnose than const violations (there should be no diagnostic after an
explicit NULL check).

> 
> If _Nullable does not create a distinct type, and `T*` is the same
> type as `T* _Nullable`, then we can't rely on the regular type system
> mechanisms to issue diagnostics.
> 
> If _Nullable creates a distinct type, then according to regular C type
> checking rules, you would get a warning on the `q = p` assignment
> regardless of the `if (!p)` check. That's how the C type system works,
> it is not flow-sensitive.
> 
> If we want the diagnostics to be fllow-sensitive like in your example
> (I think it would be the best choice), then we need to add a new
> flow-sensitive component to the C type system. I don't think there is
> a precedent for this in C right now. I'm not sure how the committee or
> implementors would react to such a proposal.

Yes, it's complex.  It should be flow-sensitive.  Right now there's a
precedent, I think: 'restrict'.  But there are no mandatory warnings
AFAIK.  This would go one step further, and would probably be the most
complex addition to the language ever.  A minimal complying compiler
would need to be much more complex than ever, which is a bad thing.

Right now I have two voices in my head saying opposite things:  on one
hand this would add a lot of complexity to the C language, and I don't
like that;  on the other hand, this would make standard C much more safe
than it is regarding pointers, and for the plain user, it would reduce
the cognitive complexity of making sure null pointers are not passed
where they shouldn't.

GCC adding _Nonnull before the standard would be a good first step.


Cheers,
Alex

  reply	other threads:[~2021-12-01 22:24 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-15 16:01 Alejandro Colomar (man-pages)
2021-11-15 16:30 ` Alejandro Colomar (man-pages)
2021-11-15 20:18 ` Joseph Myers
2021-11-15 21:09   ` Alejandro Colomar (man-pages)
2021-11-15 22:17     ` Joseph Myers
2021-11-15 22:35       ` Alejandro Colomar (man-pages)
2021-11-15 22:47         ` Joseph Myers
2021-11-16 12:34           ` Alejandro Colomar (man-pages)
2021-11-17  0:06             ` Alejandro Colomar (man-pages)
2021-11-20 16:47               ` Ping: " Alejandro Colomar (man-pages)
2021-11-23 11:32               ` [cfe-dev] " Dmitri Gribenko
2021-11-23 11:17             ` Dmitri Gribenko
2021-11-23 11:45               ` Alejandro Colomar (man-pages)
2021-11-23 12:45                 ` Dmitri Gribenko
2021-12-01 22:24                   ` Alejandro Colomar (man-pages) [this message]
2021-12-02  0:39                     ` Dmitri Gribenko
2021-12-02  1:00                       ` Alejandro Colomar (man-pages)
2021-12-02 20:24             ` Alejandro Colomar (man-pages)
2021-12-02 20:31               ` Alejandro Colomar (man-pages)
2021-12-02 20:36               ` Joseph Myers
2021-11-16  9:30     ` Jonathan Wakely
2021-11-16 17:13       ` [cfe-dev] " Arthur O'Dwyer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f6f6a77c-400f-3fa8-3e05-ac476b26b416@gmail.com \
    --to=alx.manpages@gmail.com \
    --cc=cfe-dev@lists.llvm.org \
    --cc=gcc@gcc.gnu.org \
    --cc=gribozavr@gmail.com \
    --cc=joseph@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).