Thank you, Alex. I agree this was a mistake.
>From experience, there is only one robust interface design when it comes to >null pointer arguments: either a function handles them, or it doesn't. Whether >or not it handles them should have nothing to do with the value of other >parameters. This is also how Python's type system works. I have no objection to the long-established (if it ain't broken, don't fix it) memcpy interface being upgraded to handle null pointers. The cost in CPU cycles and code size is probably negligible. What I *do* object to is a halfway house solution where memcpy only handles null pointers contingent on the value of some other parameter. This is hard to document, hard to teach static analysis tools, and hard to verify when reading calling code. I do not think it serves anyone. Best regards, Chris ________________________________________ From: Alejandro Colomar Sent: Sunday, December 01, 2024 17:24 To: qing.z...@oracle.com Cc: f...@deneb.enyo.de; gcc@gcc.gnu.org; ja...@redhat.com; josmy...@redhat.com; libc-al...@sourceware.org; uec...@tugraz.at; Chris Bazley Subject: Re: Handling C2Y zero-length operations on null pointers Hi, I had a discussion about this with another WG14 member when this was voted in. We both voted against, because this is nefarious for static analysis. However, I think this can be though to resemble how 'const' works in the standard: const char cbuf[10]; memcpy((char *)cbuf, "", 0); The code above is legal even if it is passing a const pointer where a non-const one is expected. This is because memcpy(3) will not write to it. Nevertheless, if one does memcpy(NULL, "", 0); without a cast, the compiler will still diagnose. This is important, because if we would remove the diagnostics, it would be a footgun. Similarly, we should allow null pointers (just like const pointers), in the sense that there's no Undefined Behavior. BUT there should be a diagnostic. Passing NULL is bad, and if one project wants to pass it, it should do so with whatever compiler shenanigans to disable the diagnostic (a cast, or a pragma, or whatever, not my problem). In my code, I want to see a diagnostic if I pass NULL to it, because in my dialect (and in every C language before C2y), a null pointer is an invalid pointer, and that distinction makes the code more robust. I would either transform [[gnu::nonnull]] to be only about diagnostics and not optimizations, or maybe add a _Optional qualifier that would be used for this. TL;DR: Removing UB is nice, but removing diagnostics is NOT nice. Have a lovely day! Alex P.S.: I think it was a big mistake to vote this into C2y, and I voted against. -- <https://www.alejandro-colomar.es/>