Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #169082 > unrolled thread
| Started by | Christopher Bazley <cs99cjb@gmail.com> |
|---|---|
| First post | 2023-01-28 08:15 -0800 |
| Last post | 2023-01-31 18:07 -0800 |
| Articles | 20 on this page of 66 — 15 participants |
Back to article view | Back to comp.lang.c
[RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-28 08:15 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-28 11:31 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 01:02 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 13:00 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 12:48 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 16:37 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 14:18 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 18:00 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-01-30 00:00 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-30 14:57 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Kaz Kylheku <864-117-4973@kylheku.com> - 2023-01-30 23:28 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-30 23:39 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-01-31 12:19 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-31 09:39 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Kaz Kylheku <864-117-4973@kylheku.com> - 2023-02-01 01:59 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-30 21:05 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-31 00:05 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-01-30 02:13 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Andrew Smallshaw <andrews@sdf.org> - 2023-01-29 21:52 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 14:44 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 13:17 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 16:48 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 14:36 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 18:10 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-01-29 23:33 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 18:50 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-01-30 01:05 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 21:02 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-01-30 14:11 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-30 15:22 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-01-30 02:19 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-01-30 03:16 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Harnden <richard.nospam@gmail.com> - 2023-01-30 12:48 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-01-30 14:19 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Harnden <richard.nospam@gmail.com> - 2023-01-30 18:10 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-30 15:05 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-01-31 01:15 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-01-29 02:24 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 01:21 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-01-29 13:35 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 07:21 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-01-29 13:46 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 06:54 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Oğuz <oguzismailuysal@gmail.com> - 2023-01-29 12:24 +0300
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 07:55 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 08:03 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Oğuz <oguzismailuysal@gmail.com> - 2023-01-29 20:43 +0300
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-01-29 19:03 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 22:23 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Thiago Adams <thiago.adams@gmail.com> - 2023-01-29 12:53 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 13:31 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Thiago Adams <thiago.adams@gmail.com> - 2023-01-29 13:42 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-29 14:27 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Thiago Adams <thiago.adams@gmail.com> - 2023-01-31 04:56 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Thiago Adams <thiago.adams@gmail.com> - 2023-01-29 13:46 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Richard Damon <Richard@Damon-Family.org> - 2023-01-29 16:54 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-01-31 07:54 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Christopher Bazley <cs99cjb@gmail.com> - 2023-01-31 09:25 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability bart c <bart4858@gmail.com> - 2023-01-31 14:44 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability David Brown <david.brown@hesbynett.no> - 2023-02-01 09:45 +0100
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-01-31 18:00 -0500
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-01-31 15:52 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-02-01 00:04 +0000
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability David Brown <david.brown@hesbynett.no> - 2023-02-01 09:29 +0100
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-02-01 02:31 -0800
Re: [RFC] _Optional: a type qualifier to indicate pointer nullability Siri Cruise <chine.bleu@yahoo.com> - 2023-01-31 18:07 -0800
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | Christopher Bazley <cs99cjb@gmail.com> |
|---|---|
| Date | 2023-01-29 13:17 -0800 |
| Message-ID | <8ca05fec-9aec-4837-abea-18b25221a9d6n@googlegroups.com> |
| In reply to | #169102 |
On Sunday, 29 January 2023 at 18:00:59 UTC, Richard Damon wrote: > On 1/29/23 4:02 AM, Christopher Bazley wrote: > > If your question is "Why create an _Optional qualifier instead of > > _Mandatory?" then the answer is twofold: > > > > 1. Pointers that can be null in function parameters are > > outnumbered by pointers that cannot be null without > > provoking undefined behaviour. I believe that a count of > > parameters to functions in the C standard library would > > show this, although I haven’t actually done such a count. > Which points out the high cost to implement this proposal. If the > library functions that are defined to not allow NULL pointers are going > to be changed to require pointers typed to be non-null, and functions They aren't. That's a major point of my proposal, and one reason why I think that Clang's _Nonnull attribute hasn't caught on, and never will. Programmers don't want to have to add a qualifier (or pseudo-qualifier like _Nonnull) to every pointer declaration. It's time-consuming and harms readability. Even though this is the safest (and therefore ideal) declaration of most pointers, it isn't widely used, for the same reasons: char *const x = y; This is also clearly not the language that K&R had in mind when they designed the declaration syntax is designed to mimic usage. If a side-effect of requiring only nullable pointers to be qualified is to discourage use of null pointers, I'm not sure that's a bad thing. Certainly, if a pointer can be null then it's important and I want it to SHOUT in the declaration. In contrast, reading reams of copied-and-pasted "Non-nullable pointer to..." parameter descriptions has made me hate the whole idea of explicitly documenting that (obvious) property of a pointer. A pointer to any object is not null, by definition! > It would seem the safest way to do that is leave the unadorned pointer > with the current meaning (might be null) and adding a modifier to say > that it has been checked and verified that it isn't null. > > > > 2. Assigning a pointer to a _Mandatory-qualified type to > > a pointer to an unqualified type would provoke a warning, > > whereas a pointer to an unqualified type could be > > assigned to a pointer to a _Mandatory-qualified type > > without provoking a warning. (This is the opposite of the > > required semantics for type-safety.) > Assigning a required to not be NULL pointer to a pointer that is allowed > to be NULL should absolutely NOT generate a warning, that is a perfectly > safe thing to do. I'm glad we agree. :) Nevertheless, that would be the consequence of implementing the same semantics for _Mandatory as for all of the existing qualifiers. Currently, the semantics of C follow directly from its declaration syntax. Your proposal would wreck that. > It doesn't matter which one has the extra marking, it matters on which > is the more permissive. "Type Safety" isn't about denoted vs undenoted > but premissive vs restrictive. Yes, it says this modifier works the > opposite of const and volatile, where safe is unmarked to marked, but > that just says that if this was created 50 years ago, the better would > have been a "Nullable" modifier. Nothing keeps the language from having > two types of modifiers that act differently. It's true that there is nothing in principle stopping different type qualifiers having different semantics for function calls, assignments, initializations and compatibility of declarations, but that isn't the kind of language I want to use, therefore it's not the kind of extension I proposed. If not for my night terrors about someone else proposing such an extension to C, I probably wouldn't have invested months in prototyping and testing my alternative. I don't rule out such an idea being accepted and all my work being for nothing, but as far as I know nobody has written such a paper or created a working implementation of it. > Note also, this is different than const and volatile anyway, as there is > no such thing as a "Optional" object, all objects exist (unless this is > going to try to put the "weak" declaration from GCC into the standard. As far as I know, I invented the syntax of an optional object in C but it's a long-established concept. I think it's perfectly valid, and it has precedents in other languages. Nothing to do with weak declarations. Note that use of the _Optional qualifier in declarations except to qualify the type of a pointee is disallowed (with exceptions for typedefs, because they aren't the final declaration of a type, and function parameters using [] syntax, because they actually declare a pointer). Cheers Christopher
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2023-01-29 16:48 -0500 |
| Message-ID | <mQBBL.341279$Tcw8.300895@fx10.iad> |
| In reply to | #169105 |
On 1/29/23 4:17 PM, Christopher Bazley wrote: > On Sunday, 29 January 2023 at 18:00:59 UTC, Richard Damon wrote: >> On 1/29/23 4:02 AM, Christopher Bazley wrote: >>> If your question is "Why create an _Optional qualifier instead of >>> _Mandatory?" then the answer is twofold: >>> >>> 1. Pointers that can be null in function parameters are >>> outnumbered by pointers that cannot be null without >>> provoking undefined behaviour. I believe that a count of >>> parameters to functions in the C standard library would >>> show this, although I haven’t actually done such a count. >> Which points out the high cost to implement this proposal. If the >> library functions that are defined to not allow NULL pointers are going >> to be changed to require pointers typed to be non-null, and functions > > They aren't. That's a major point of my proposal, and one reason > why I think that Clang's _Nonnull attribute hasn't caught on, and > never will. Programmers don't want to have to add a qualifier > (or pseudo-qualifier like _Nonnull) to every pointer declaration. > It's time-consuming and harms readability. > > Even though this is the safest (and therefore ideal) declaration of > most pointers, it isn't widely used, for the same reasons: > > char *const x = y; > > This is also clearly not the language that K&R had in mind when > they designed the declaration syntax is designed to mimic usage. > > If a side-effect of requiring only nullable pointers to be qualified is > to discourage use of null pointers, I'm not sure that's a bad thing. > > Certainly, if a pointer can be null then it's important and I want it > to SHOUT in the declaration. In contrast, reading reams of > copied-and-pasted "Non-nullable pointer to..." parameter > descriptions has made me hate the whole idea of explicitly > documenting that (obvious) property of a pointer. A pointer to any > object is not null, by definition! > >> It would seem the safest way to do that is leave the unadorned pointer >> with the current meaning (might be null) and adding a modifier to say >> that it has been checked and verified that it isn't null. >>> >>> 2. Assigning a pointer to a _Mandatory-qualified type to >>> a pointer to an unqualified type would provoke a warning, >>> whereas a pointer to an unqualified type could be >>> assigned to a pointer to a _Mandatory-qualified type >>> without provoking a warning. (This is the opposite of the >>> required semantics for type-safety.) >> Assigning a required to not be NULL pointer to a pointer that is allowed >> to be NULL should absolutely NOT generate a warning, that is a perfectly >> safe thing to do. > > I'm glad we agree. :) Nevertheless, that would be the consequence of > implementing the same semantics for _Mandatory as for all of the > existing qualifiers. Currently, the semantics of C follow directly from its > declaration syntax. Your proposal would wreck that. Nope, only if you defined that it had to work like const or volatile, it doesn't Think like C++ and assignments between pointers to derived and base classs. > >> It doesn't matter which one has the extra marking, it matters on which >> is the more permissive. "Type Safety" isn't about denoted vs undenoted >> but premissive vs restrictive. Yes, it says this modifier works the >> opposite of const and volatile, where safe is unmarked to marked, but >> that just says that if this was created 50 years ago, the better would >> have been a "Nullable" modifier. Nothing keeps the language from having >> two types of modifiers that act differently. > > It's true that there is nothing in principle stopping different type qualifiers > having different semantics for function calls, assignments, initializations > and compatibility of declarations, but that isn't the kind of language > I want to use, therefore it's not the kind of extension I proposed. But that says that you are defining that if the extension actually is to enforce in code, it will by necessity break almost every program in existance. > > If not for my night terrors about someone else proposing such an > extension to C, I probably wouldn't have invested months in prototyping > and testing my alternative. I don't rule out such an idea being accepted > and all my work being for nothing, but as far as I know nobody has > written such a paper or created a working implementation of it. > >> Note also, this is different than const and volatile anyway, as there is >> no such thing as a "Optional" object, all objects exist (unless this is >> going to try to put the "weak" declaration from GCC into the standard. > > As far as I know, I invented the syntax of an optional object in C > but it's a long-established concept. I think it's perfectly valid, and > it has precedents in other languages. Nothing to do with weak > declarations. Which shows that it is a DEFERNT thing than const and volatile, as those are properties of OBJECTS, that carry over to the addresses taken of them. If there are no "Optional" objects, then it is a different sort of modifier. Remember, ultimately, const and volatile define the rules for accessing the end object, but your optional doesn't. > > Note that use of the _Optional qualifier in declarations except to > qualify the type of a pointee is disallowed (with exceptions for > typedefs, because they aren't the final declaration of a type, > and function parameters using [] syntax, because they actually > declare a pointer). > I will point out that your notation isn't that different from something similar in Python to indicate that a parameter is optiona. The key difference is that in Python, the notation is SPECIFICLY marked as having (virtually) ZERO effect on the compiler, and only has meaning for a linter. (Virtually, as if you use inspection to get the definition of the function, the optional word is still there). > Cheers > Christopher
[toc] | [prev] | [next] | [standalone]
| From | Christopher Bazley <cs99cjb@gmail.com> |
|---|---|
| Date | 2023-01-29 14:36 -0800 |
| Message-ID | <cc9e43a6-c88f-4e47-b2aa-30a3a01d5a56n@googlegroups.com> |
| In reply to | #169112 |
On Sunday, 29 January 2023 at 21:48:16 UTC, Richard Damon wrote: > On 1/29/23 4:17 PM, Christopher Bazley wrote: > > I'm glad we agree. :) Nevertheless, that would be the consequence of > > implementing the same semantics for _Mandatory as for all of the > > existing qualifiers. Currently, the semantics of C follow directly from its > > declaration syntax. Your proposal would wreck that. > Nope, only if you defined that it had to work like const or volatile, it > doesn't > > Think like C++ and assignments between pointers to derived and base classs. I don't want to think like C++. This is comp.lang.c, isn't it? > >> It doesn't matter which one has the extra marking, it matters on which > >> is the more permissive. "Type Safety" isn't about denoted vs undenoted > >> but premissive vs restrictive. Yes, it says this modifier works the > >> opposite of const and volatile, where safe is unmarked to marked, but > >> that just says that if this was created 50 years ago, the better would > >> have been a "Nullable" modifier. Nothing keeps the language from having > >> two types of modifiers that act differently. > > > > It's true that there is nothing in principle stopping different type qualifiers > > having different semantics for function calls, assignments, initializations > > and compatibility of declarations, but that isn't the kind of language > > I want to use, therefore it's not the kind of extension I proposed. > But that says that you are defining that if the extension actually is to > enforce in code, it will by necessity break almost every program in > existance. I doesn't break any program in existence. Not even one. Nobody is forcing anyone to use the new qualifier that I am proposing, any more than C programmers are forced to use 'const'. I explained routes to gradual adoption in my paper. > > As far as I know, I invented the syntax of an optional object in C > > but it's a long-established concept. I think it's perfectly valid, and > > it has precedents in other languages. Nothing to do with weak > > declarations. > Which shows that it is a DEFERNT thing than const and volatile, as those > are properties of OBJECTS, that carry over to the addresses taken of > them. If there are no "Optional" objects, then it is a different sort of > modifier. There are optional objects. This expression adds the value of two optional objects: int x = 10, y = 20; _Optional int *xp = &x, *yp = &y; int sum = *xp + *yp; The fact that the objects are optional is neither here nor there when it comes to performing arithmetic on them. The above code has well-defined behaviour. > Remember, ultimately, const and volatile define the rules for accessing > the end object, but your optional doesn't. It does. I don't think I can explain it any more clearly than in the many thousands of words I already wrote on the matter.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2023-01-29 18:10 -0500 |
| Message-ID | <g1DBL.523656$vBI8.176300@fx15.iad> |
| In reply to | #169118 |
On 1/29/23 5:36 PM, Christopher Bazley wrote: > On Sunday, 29 January 2023 at 21:48:16 UTC, Richard Damon wrote: >> On 1/29/23 4:17 PM, Christopher Bazley wrote: >>> I'm glad we agree. :) Nevertheless, that would be the consequence of >>> implementing the same semantics for _Mandatory as for all of the >>> existing qualifiers. Currently, the semantics of C follow directly from its >>> declaration syntax. Your proposal would wreck that. >> Nope, only if you defined that it had to work like const or volatile, it >> doesn't >> >> Think like C++ and assignments between pointers to derived and base classs. > > I don't want to think like C++. This is comp.lang.c, isn't it? > >>>> It doesn't matter which one has the extra marking, it matters on which >>>> is the more permissive. "Type Safety" isn't about denoted vs undenoted >>>> but premissive vs restrictive. Yes, it says this modifier works the >>>> opposite of const and volatile, where safe is unmarked to marked, but >>>> that just says that if this was created 50 years ago, the better would >>>> have been a "Nullable" modifier. Nothing keeps the language from having >>>> two types of modifiers that act differently. >>> >>> It's true that there is nothing in principle stopping different type qualifiers >>> having different semantics for function calls, assignments, initializations >>> and compatibility of declarations, but that isn't the kind of language >>> I want to use, therefore it's not the kind of extension I proposed. >> But that says that you are defining that if the extension actually is to >> enforce in code, it will by necessity break almost every program in >> existance. > > I doesn't break any program in existence. Not even one. > Nobody is forcing anyone to use the new qualifier that I am proposing, > any more than C programmers are forced to use 'const'. > I explained routes to gradual adoption in my paper. Except that all calls to malloc (or any library function that returns a possibly null pointer) will see a _Optional void* pointer which will generate the diagnostic when assigned. Remember, any diagnostic required by the Standard makes using the program that results to be undefined behavior, The Standard doesn't talk about Errors and Warnings, only Diagnostics. > >>> As far as I know, I invented the syntax of an optional object in C >>> but it's a long-established concept. I think it's perfectly valid, and >>> it has precedents in other languages. Nothing to do with weak >>> declarations. >> Which shows that it is a DEFERNT thing than const and volatile, as those >> are properties of OBJECTS, that carry over to the addresses taken of >> them. If there are no "Optional" objects, then it is a different sort of >> modifier. > > There are optional objects. This expression adds the value of two > optional objects: > > int x = 10, y = 20; > _Optional int *xp = &x, *yp = &y; No, xp is "Optional" the type it points to is qualified as optional. just like char const* ptr; doesn't make a constant pointer, but a pointer to constant. char* const ptr; Makes a pointer to a mutable buffer that you can not change the pointer to, thus there ptr is a const object. > int sum = *xp + *yp; > > The fact that the objects are optional is neither here nor there when > it comes to performing arithmetic on them. The above code has > well-defined behaviour. Except that _Optional int* xp; doesn't define a objecct that has the _Optional modifier as part f the base object type. The optional part is to the type of the "object" it is pointing to, but there is no way to actually make such an object. > >> Remember, ultimately, const and volatile define the rules for accessing >> the end object, but your optional doesn't. > > It does. I don't think I can explain it any more clearly than in the many > thousands of words I already wrote on the matter. >
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-01-29 23:33 +0000 |
| Message-ID | <871qncud9z.fsf@bsb.me.uk> |
| In reply to | #169121 |
Richard Damon <Richard@Damon-Family.org> writes: > On 1/29/23 5:36 PM, Christopher Bazley wrote: >> There are optional objects. This expression adds the value of two >> optional objects: Technically no. It add the values of two objects with effective type int via two lvalue expressions of type _Optional int. There's an object, and the type of lvalue expression used to access it. >> int x = 10, y = 20; >> _Optional int *xp = &x, *yp = &y; > > No, xp is "Optional" the type it points to is qualified as optional. (I think you missed out a "not" here. xp is not _Optional qualified.) >> int sum = *xp + *yp; >> The fact that the objects are optional is neither here nor there when >> it comes to performing arithmetic on them. The above code has >> well-defined behaviour. > > Except that _Optional int* xp; > > doesn't define a objecct that has the _Optional modifier as part f the > base object type. The optional part is to the type of the "object" it > is pointing to, but there is no way to actually make such an object. I think this discussion will get tied up in knots unless everyone distinguishes between the type of the objects (really the effective type of the object, see 6.5 p6) and the type of the lvalue expressions used to access them. The effective type of objects whose values are being added is int. The type of the lvalue expressions used to access them is _Optional int. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2023-01-29 18:50 -0500 |
| Message-ID | <VCDBL.523658$vBI8.29915@fx15.iad> |
| In reply to | #169122 |
On 1/29/23 6:33 PM, Ben Bacarisse wrote: > Richard Damon <Richard@Damon-Family.org> writes: > >> On 1/29/23 5:36 PM, Christopher Bazley wrote: > >>> There are optional objects. This expression adds the value of two >>> optional objects: > > Technically no. It add the values of two objects with effective type > int via two lvalue expressions of type _Optional int. There's an > object, and the type of lvalue expression used to access it. > >>> int x = 10, y = 20; >>> _Optional int *xp = &x, *yp = &y; >> >> No, xp is "Optional" the type it points to is qualified as optional. > > (I think you missed out a "not" here. xp is not _Optional qualified.) > >>> int sum = *xp + *yp; >>> The fact that the objects are optional is neither here nor there when >>> it comes to performing arithmetic on them. The above code has >>> well-defined behaviour. >> >> Except that _Optional int* xp; >> >> doesn't define a objecct that has the _Optional modifier as part f the >> base object type. The optional part is to the type of the "object" it >> is pointing to, but there is no way to actually make such an object. > > I think this discussion will get tied up in knots unless everyone > distinguishes between the type of the objects (really the effective type > of the object, see 6.5 p6) and the type of the lvalue expressions used > to access them. > > The effective type of objects whose values are being added is int. The > type of the lvalue expressions used to access them is _Optional int. > Yes, that is the distinction that I am trying to point out. From his description there can not actually be an object of type "_Optional int", just an lvalue expression with that type, And that modifier doesn't actually change any behavior of the access of the object of that effective type. Either the access is just totally prohibited and a diagnostic required in using thta object, or it happens exactly as the unqualified object (apart from the suggestion to generate a "warning").
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-01-30 01:05 +0000 |
| Message-ID | <87y1pkrfvm.fsf@bsb.me.uk> |
| In reply to | #169123 |
Richard Damon <Richard@Damon-Family.org> writes:
> On 1/29/23 6:33 PM, Ben Bacarisse wrote:
>> Richard Damon <Richard@Damon-Family.org> writes:
>>
>>> On 1/29/23 5:36 PM, Christopher Bazley wrote:
>>
>>>> There are optional objects. This expression adds the value of two
>>>> optional objects:
>> Technically no. It add the values of two objects with effective type
>> int via two lvalue expressions of type _Optional int. There's an
>> object, and the type of lvalue expression used to access it.
>>
>>>> int x = 10, y = 20;
>>>> _Optional int *xp = &x, *yp = &y;
>>>
>>> No, xp is "Optional" the type it points to is qualified as optional.
>> (I think you missed out a "not" here. xp is not _Optional qualified.)
>>
>>>> int sum = *xp + *yp;
>>>> The fact that the objects are optional is neither here nor there when
>>>> it comes to performing arithmetic on them. The above code has
>>>> well-defined behaviour.
>>>
>>> Except that _Optional int* xp;
>>>
>>> doesn't define a objecct that has the _Optional modifier as part f the
>>> base object type. The optional part is to the type of the "object" it
>>> is pointing to, but there is no way to actually make such an object.
>>
>> I think this discussion will get tied up in knots unless everyone
>> distinguishes between the type of the objects (really the effective type
>> of the object, see 6.5 p6) and the type of the lvalue expressions used
>> to access them.
>> The effective type of objects whose values are being added is int. The
>> type of the lvalue expressions used to access them is _Optional int.
>
> Yes, that is the distinction that I am trying to point out.
I thought so, but I also thought pointing out the words used by the
standard might help keep the discussion clear.
> From his description there can not actually be an object of type
> "_Optional int",
Where do you get that from? I admit to have started skimming before
getting to core of the technical part, so I might have missed this, but
I did not see any prohibition on declaring _Optional int oi = 42;
More interesting, though, is that the effective type of allocated memory
can become an _Optional qualified type. As I read it, after
void fill_int(void *allocated_mem, _Optional int *oip)
{
memcpy(alloced_mem, oip, sizeof *oip);
}
then the effective type of (the start of) the "allocated_mem" becomes
_Optional int for this and all subsequent non-modifying accesses.
> And that modifier doesn't actually change any behavior of the access
> of the object of that effective type.
Yes, the effective type rules allow extra qualifiers in the type of the
accessing lvalue expression.
> Either the access is just totally prohibited and a diagnostic required
> in using thta object, or it happens exactly as the unqualified object
> (apart from the suggestion to generate a "warning").
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2023-01-29 21:02 -0500 |
| Message-ID | <gzFBL.148958$PXw7.43641@fx45.iad> |
| In reply to | #169125 |
On 1/29/23 8:05 PM, Ben Bacarisse wrote:
> Richard Damon <Richard@Damon-Family.org> writes:
>
>> On 1/29/23 6:33 PM, Ben Bacarisse wrote:
>>> Richard Damon <Richard@Damon-Family.org> writes:
>>>
>>>> On 1/29/23 5:36 PM, Christopher Bazley wrote:
>>>
>>>>> There are optional objects. This expression adds the value of two
>>>>> optional objects:
>>> Technically no. It add the values of two objects with effective type
>>> int via two lvalue expressions of type _Optional int. There's an
>>> object, and the type of lvalue expression used to access it.
>>>
>>>>> int x = 10, y = 20;
>>>>> _Optional int *xp = &x, *yp = &y;
>>>>
>>>> No, xp is "Optional" the type it points to is qualified as optional.
>>> (I think you missed out a "not" here. xp is not _Optional qualified.)
>>>
>>>>> int sum = *xp + *yp;
>>>>> The fact that the objects are optional is neither here nor there when
>>>>> it comes to performing arithmetic on them. The above code has
>>>>> well-defined behaviour.
>>>>
>>>> Except that _Optional int* xp;
>>>>
>>>> doesn't define a objecct that has the _Optional modifier as part f the
>>>> base object type. The optional part is to the type of the "object" it
>>>> is pointing to, but there is no way to actually make such an object.
>>>
>>> I think this discussion will get tied up in knots unless everyone
>>> distinguishes between the type of the objects (really the effective type
>>> of the object, see 6.5 p6) and the type of the lvalue expressions used
>>> to access them.
>>> The effective type of objects whose values are being added is int. The
>>> type of the lvalue expressions used to access them is _Optional int.
>>
>> Yes, that is the distinction that I am trying to point out.
>
> I thought so, but I also thought pointing out the words used by the
> standard might help keep the discussion clear.
>
>> From his description there can not actually be an object of type
>> "_Optional int",
>
> Where do you get that from? I admit to have started skimming before
> getting to core of the technical part, so I might have missed this, but
> I did not see any prohibition on declaring _Optional int oi = 42;
I asked him about declairing an actual object as a _Optional type (and
what would that mean, the closes I can think of would be something like
GCC weak attribute).
He said that you couldn't do that. _Optional was to be use ONLY on the
type destination of a pointer.
>
> More interesting, though, is that the effective type of allocated memory
> can become an _Optional qualified type. As I read it, after
>
> void fill_int(void *allocated_mem, _Optional int *oip)
> {
> memcpy(alloced_mem, oip, sizeof *oip);
> }
>
> then the effective type of (the start of) the "allocated_mem" becomes
> _Optional int for this and all subsequent non-modifying accesses.
>
>> And that modifier doesn't actually change any behavior of the access
>> of the object of that effective type.
>
> Yes, the effective type rules allow extra qualifiers in the type of the
> accessing lvalue expression.
but access a non-qualified object via a qualified effective type is
defined to assess that object as if it was of that type. Most
importantly for volatile, sicne that might have real hardware
differences to the access depending on the implentation.
>
>> Either the access is just totally prohibited and a diagnostic required
>> in using thta object, or it happens exactly as the unqualified object
>> (apart from the suggestion to generate a "warning").
>
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-01-30 14:11 +0000 |
| Message-ID | <874js8qfii.fsf@bsb.me.uk> |
| In reply to | #169127 |
Richard Damon <Richard@Damon-Family.org> writes:
> On 1/29/23 8:05 PM, Ben Bacarisse wrote:
>> Richard Damon <Richard@Damon-Family.org> writes:
>>
>>> On 1/29/23 6:33 PM, Ben Bacarisse wrote:
>>>> Richard Damon <Richard@Damon-Family.org> writes:
>>>>
>>>>> On 1/29/23 5:36 PM, Christopher Bazley wrote:
>>>>
>>>>>> There are optional objects. This expression adds the value of two
>>>>>> optional objects:
>>>> Technically no. It add the values of two objects with effective type
>>>> int via two lvalue expressions of type _Optional int. There's an
>>>> object, and the type of lvalue expression used to access it.
>>>>
>>>>>> int x = 10, y = 20;
>>>>>> _Optional int *xp = &x, *yp = &y;
>>>>>
>>>>> No, xp is "Optional" the type it points to is qualified as optional.
>>>> (I think you missed out a "not" here. xp is not _Optional qualified.)
>>>>
>>>>>> int sum = *xp + *yp;
>>>>>> The fact that the objects are optional is neither here nor there when
>>>>>> it comes to performing arithmetic on them. The above code has
>>>>>> well-defined behaviour.
>>>>>
>>>>> Except that _Optional int* xp;
>>>>>
>>>>> doesn't define a objecct that has the _Optional modifier as part f the
>>>>> base object type. The optional part is to the type of the "object" it
>>>>> is pointing to, but there is no way to actually make such an object.
>>>>
>>>> I think this discussion will get tied up in knots unless everyone
>>>> distinguishes between the type of the objects (really the effective type
>>>> of the object, see 6.5 p6) and the type of the lvalue expressions used
>>>> to access them.
>>>> The effective type of objects whose values are being added is int. The
>>>> type of the lvalue expressions used to access them is _Optional int.
>>>
>>> Yes, that is the distinction that I am trying to point out.
>> I thought so, but I also thought pointing out the words used by the
>> standard might help keep the discussion clear.
>>
>>> From his description there can not actually be an object of type
>>> "_Optional int",
>> Where do you get that from? I admit to have started skimming before
>> getting to core of the technical part, so I might have missed this, but
>> I did not see any prohibition on declaring _Optional int oi = 42;
>
> I asked him about declairing an actual object as a _Optional type (and
> what would that mean, the closes I can think of would be something
> like GCC weak attribute).
>
> He said that you couldn't do that. _Optional was to be use ONLY on the
> type destination of a pointer.
Curious. I'd consider that a flaw in the proposal unless it prevents
some really serious errors. Having the fewest special cases is a good
thing to aim for, even if that results is some pointless uses.
>> More interesting, though, is that the effective type of allocated memory
>> can become an _Optional qualified type. As I read it, after
>> void fill_int(void *allocated_mem, _Optional int *oip)
>> {
>> memcpy(alloced_mem, oip, sizeof *oip);
>> }
>> then the effective type of (the start of) the "allocated_mem" becomes
>> _Optional int for this and all subsequent non-modifying accesses.
I'm not sure this is correct if there can't be any _Optional qualified
objects to copy from. A better example would be
_Optional int *oip = malloc(sizeof(int));
// now the expression *oip has effective type _Optional int
since the effective type of the allocated object is now just that of the
lvalue expression used to access it.
>>> And that modifier doesn't actually change any behavior of the access
>>> of the object of that effective type.
>> Yes, the effective type rules allow extra qualifiers in the type of the
>> accessing lvalue expression.
>
> but access a non-qualified object via a qualified effective type is
> defined to assess that object as if it was of that type. Most
> importantly for volatile, sicne that might have real hardware
> differences to the access depending on the implentation.
I'm not sure that is a general rule. There is specific wording that
ensures that access to an object via a volatile qualified lvalue is a
volatile access. But I don't think it matters since no special wording
is proposed about accesses to or via _Optional qualified types.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Christopher Bazley <cs99cjb@gmail.com> |
|---|---|
| Date | 2023-01-30 15:22 -0800 |
| Message-ID | <93912e33-6c1b-416b-a8d9-9d677a06d1b8n@googlegroups.com> |
| In reply to | #169138 |
On Monday, 30 January 2023 at 14:11:18 UTC, Ben Bacarisse wrote: > Richard Damon <Ric...@Damon-Family.org> writes: > > I asked him about declairing an actual object as a _Optional type (and > > what would that mean, the closes I can think of would be something > > like GCC weak attribute). > > > > He said that you couldn't do that. _Optional was to be use ONLY on the > > type destination of a pointer. Correct. > Curious. I'd consider that a flaw in the proposal unless it prevents > some really serious errors. Having the fewest special cases is a good > thing to aim for, even if that results is some pointless uses. I totally agree but it's not a hill I'm willing to die on. I originally intended _Optional to be usable in any part of a declaration and only banned its use at top level based on feedback from others. One interesting thing pointed out by a Redditor is that banning usage of _Optional at top level could be justified better if so-qualified values could not exist as the result of dereferencing a pointer, yet I proposed no change to the semantics of *, -> and [] for the new type qualifier. I'd be just as happy for pointer dereference operations to implicitly remove the _Optional qualifier from their result. I already have code to implement that behaviour for Clang kicking around on a local branch somewhere, and I wrote all the wording for the alternative proposal but ultimately didn't use it. 99% of programs using _Optional would work without modification with either implementation. The reasons that I specified that & should remove the _Optional qualifier instead of *, [] and -> are given in my paper, but they aren't incontestable. Cheers, Christopher
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2023-01-30 02:19 -0500 |
| Message-ID | <tr7r23$35nnv$1@dont-email.me> |
| In reply to | #169092 |
On 1/29/23 04:02, Christopher Bazley wrote: > On Saturday, 28 January 2023 at 16:31:49 UTC, Richard Damon wrote: >> On 1/28/23 11:15 AM, Christopher Bazley wrote: >>> Hi all, >>> >>> I've just submitted my paper n3089, “_Optional: a type qualifier to indicate pointer nullability” to the WG14 committee. >> Since the current default of a pointer type is to allow null values, >> wouldn't you need a modifier to say it can't be null, otherwise you >> break all existing code with the change. > > Hi Richard, > > I believe that I addressed that question in the 'Migration of > existing code' part of my proposal: > >> Requiring implementations to redefine the constant to which the >> NULL macro expands as ((_Optional void *)0) is unthinkable >> because it would invalidate all existing code. However, it might >> be useful to standardize an alternative macro for use in place >> of NULL. I have not specified such a macro because NULL is >> not a core part of the language. NULL is specified by the C standard. If you're suggesting changes to the part of the standard that describes the language, you should include corresponding changes to the part of the standard that describes the standard library. The committee doesn't make such artificial distinctions - it will need to consider both kinds of changes at the same time. > If your question is "Why create an _Optional qualifier instead of > _Mandatory?" then the answer is twofold: > > 1. Pointers that can be null in function parameters are > outnumbered by pointers that cannot be null without > provoking undefined behaviour. I believe that a count of > parameters to functions in the C standard library would > show this, although I haven’t actually done such a count. It doesn't matter which kind of pointers are more common. Both kinds of pointers are sufficiently common that it would be grotesquely unacceptable to break existing code using either kind of pointer. Backwards compatibility is a major concern of the committee. Any proposed changes to the language should, in general, leave the behavior of existing code unchanged; only code that applies the new qualifier should have different behavior.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2023-01-30 03:16 -0800 |
| Message-ID | <78f04452-b9c9-4388-8b2c-5f2cd283ec12n@googlegroups.com> |
| In reply to | #169135 |
On Monday, 30 January 2023 at 07:19:44 UTC, james...@alumni.caltech.edu wrote: > On 1/29/23 04:02, Christopher Bazley wrote: > > > 1. Pointers that can be null in function parameters are > > outnumbered by pointers that cannot be null without > > provoking undefined behaviour. I believe that a count of > > parameters to functions in the C standard library would > > show this, although I haven’t actually done such a count. > It doesn't matter which kind of pointers are more common. Both kinds of > pointers are sufficiently common that it would be grotesquely > unacceptable to break existing code using either kind of pointer. > Backwards compatibility is a major concern of the committee. Any > proposed changes to the language should, in general, leave the behavior > of existing code unchanged; only code that applies the new qualifier > should have different behavior. > There's also a grey area. Consider the unexceptional function void payroll(EMPLOYEE *employees, int Nemployees) Obviously if Nemployees is greater than zero, employees cannot be null. But can the function be called on a zero-sized payroll?
[toc] | [prev] | [next] | [standalone]
| From | Richard Harnden <richard.nospam@gmail.com> |
|---|---|
| Date | 2023-01-30 12:48 +0000 |
| Message-ID | <tr8eb8$39ru4$1@dont-email.me> |
| In reply to | #169136 |
On 30/01/2023 11:16, Malcolm McLean wrote: > On Monday, 30 January 2023 at 07:19:44 UTC, james...@alumni.caltech.edu wrote: >> On 1/29/23 04:02, Christopher Bazley wrote: >> >>> 1. Pointers that can be null in function parameters are >>> outnumbered by pointers that cannot be null without >>> provoking undefined behaviour. I believe that a count of >>> parameters to functions in the C standard library would >>> show this, although I haven’t actually done such a count. >> It doesn't matter which kind of pointers are more common. Both kinds of >> pointers are sufficiently common that it would be grotesquely >> unacceptable to break existing code using either kind of pointer. >> Backwards compatibility is a major concern of the committee. Any >> proposed changes to the language should, in general, leave the behavior >> of existing code unchanged; only code that applies the new qualifier >> should have different behavior. >> > There's also a grey area. Consider the unexceptional function > > void payroll(EMPLOYEE *employees, int Nemployees) > > Obviously if Nemployees is greater than zero, employees cannot be null. > But can the function be called on a zero-sized payroll? That's common, surely: char *s = NULL; size_t have = 0; size_t need; need = snprintf(s, have, ...) + 1;
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-01-30 14:19 +0000 |
| Message-ID | <87wn54p0k0.fsf@bsb.me.uk> |
| In reply to | #169137 |
Richard Harnden <richard.nospam@gmail.com> writes: > On 30/01/2023 11:16, Malcolm McLean wrote: >> On Monday, 30 January 2023 at 07:19:44 UTC, james...@alumni.caltech.edu wrote: >>> On 1/29/23 04:02, Christopher Bazley wrote: >>> >>>> 1. Pointers that can be null in function parameters are >>>> outnumbered by pointers that cannot be null without >>>> provoking undefined behaviour. I believe that a count of >>>> parameters to functions in the C standard library would >>>> show this, although I haven’t actually done such a count. >>> It doesn't matter which kind of pointers are more common. Both kinds of >>> pointers are sufficiently common that it would be grotesquely >>> unacceptable to break existing code using either kind of pointer. >>> Backwards compatibility is a major concern of the committee. Any >>> proposed changes to the language should, in general, leave the behavior >>> of existing code unchanged; only code that applies the new qualifier >>> should have different behavior. >>> >> There's also a grey area. Consider the unexceptional function >> void payroll(EMPLOYEE *employees, int Nemployees) >> Obviously if Nemployees is greater than zero, employees cannot be null. >> But can the function be called on a zero-sized payroll? > > That's common, surely: > char *s = NULL; > size_t have = 0; > size_t need; > > need = snprintf(s, have, ...) + 1; Yes, it's common, but the answer isn't uniform. snprintf has particular wording that makes your call legal, but memcpy(s, "hello", have); is not. For the majority of C standard library functions, pointer arguments must be valid even if there is an associated zero size or length argument that, logically, implies that no accesses should be done. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Richard Harnden <richard.nospam@gmail.com> |
|---|---|
| Date | 2023-01-30 18:10 +0000 |
| Message-ID | <tr917g$3co7l$1@dont-email.me> |
| In reply to | #169139 |
On 30/01/2023 14:19, Ben Bacarisse wrote: > Richard Harnden <richard.nospam@gmail.com> writes: > >> On 30/01/2023 11:16, Malcolm McLean wrote: >>> On Monday, 30 January 2023 at 07:19:44 UTC, james...@alumni.caltech.edu wrote: >>>> On 1/29/23 04:02, Christopher Bazley wrote: >>>> >>>>> 1. Pointers that can be null in function parameters are >>>>> outnumbered by pointers that cannot be null without >>>>> provoking undefined behaviour. I believe that a count of >>>>> parameters to functions in the C standard library would >>>>> show this, although I haven’t actually done such a count. >>>> It doesn't matter which kind of pointers are more common. Both kinds of >>>> pointers are sufficiently common that it would be grotesquely >>>> unacceptable to break existing code using either kind of pointer. >>>> Backwards compatibility is a major concern of the committee. Any >>>> proposed changes to the language should, in general, leave the behavior >>>> of existing code unchanged; only code that applies the new qualifier >>>> should have different behavior. >>>> >>> There's also a grey area. Consider the unexceptional function >>> void payroll(EMPLOYEE *employees, int Nemployees) >>> Obviously if Nemployees is greater than zero, employees cannot be null. >>> But can the function be called on a zero-sized payroll? >> >> That's common, surely: >> char *s = NULL; >> size_t have = 0; >> size_t need; >> >> need = snprintf(s, have, ...) + 1; > > Yes, it's common, but the answer isn't uniform. snprintf has particular > wording that makes your call legal, but > > memcpy(s, "hello", have); > > is not. For the majority of C standard library functions, pointer > arguments must be valid even if there is an associated zero size or > length argument that, logically, implies that no accesses should be > done. > Yes, so it's my responsablity to pass a valid pointer. I wonder what is more common, though: a pointer that's NULL by mistake, or a non-NULL pointer that's been free'd by mistake.
[toc] | [prev] | [next] | [standalone]
| From | Christopher Bazley <cs99cjb@gmail.com> |
|---|---|
| Date | 2023-01-30 15:05 -0800 |
| Message-ID | <8f85d06d-d274-49a1-bb86-a0c249f19ff3n@googlegroups.com> |
| In reply to | #169135 |
On Monday, 30 January 2023 at 07:19:44 UTC, james...@alumni.caltech.edu wrote: > On 1/29/23 04:02, Christopher Bazley wrote: > > On Saturday, 28 January 2023 at 16:31:49 UTC, Richard Damon wrote: > >> On 1/28/23 11:15 AM, Christopher Bazley wrote: > >> Requiring implementations to redefine the constant to which the > >> NULL macro expands as ((_Optional void *)0) is unthinkable > >> because it would invalidate all existing code. However, it might > >> be useful to standardize an alternative macro for use in place > >> of NULL. I have not specified such a macro because NULL is > >> not a core part of the language. > NULL is specified by the C standard. I think we all know that. > If you're suggesting changes to the > part of the standard that describes the language, you should include > corresponding changes to the part of the standard that describes the > standard library. I did not specify changes to the part of the standard that describes the standard library, because no such changes are necessary. > > If your question is "Why create an _Optional qualifier instead of > > _Mandatory?" then the answer is twofold: > > > > 1. Pointers that can be null in function parameters are > > outnumbered by pointers that cannot be null without > > provoking undefined behaviour. I believe that a count of > > parameters to functions in the C standard library would > > show this, although I haven’t actually done such a count. > It doesn't matter which kind of pointers are more common. Both kinds of > pointers are sufficiently common that it would be grotesquely > unacceptable to break existing code using either kind of pointer. I didn't mean to imply otherwise. My argument for not forcing mandatory arguments to be qualified had nothing to do with backwards compatibility. I think that one reason that _Nonnull isn't popular and never will be (apart from the fact that only Clang supports it) is that cluttering the 90% of pointer arguments which cannot be null with an extra qualifier is ugly and time-wasting. Cheers, Christopher
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2023-01-31 01:15 -0500 |
| Message-ID | <trabln$3mcg7$1@dont-email.me> |
| In reply to | #169143 |
On 1/30/23 18:05, Christopher Bazley wrote: > On Monday, 30 January 2023 at 07:19:44 UTC, > james...@alumni.caltech.edu wrote: >> On 1/29/23 04:02, Christopher Bazley wrote: ... >> If you're suggesting changes to the part of the standard that >> describes the language, you should include corresponding changes to >> the part of the standard that describes the standard library. > > I did not specify changes to the part of the standard that describes the > standard library, because no such changes are necessary. But such changes should be made, if there's any point in adopting this feature, then there should be some standard library functions which should use the feature, where appropriate. ... >>> 1. Pointers that can be null in function parameters are outnumbered >>> by pointers that cannot be null without provoking undefined >>> behaviour. I believe that a count of parameters to functions in the >>> C standard library would show this, although I haven’t actually done >>> such a count. >> It doesn't matter which kind of pointers are more common. Both kinds >> of pointers are sufficiently common that it would be grotesquely >> unacceptable to break existing code using either kind of pointer. > > I didn't mean to imply otherwise. My argument for not > forcing mandatory arguments to be qualified had nothing > to do with backwards compatibility. I think that one reason > that _Nonnull isn't popular and never will be (apart from the > fact that only Clang supports it) is that cluttering the 90% > of pointer arguments which cannot be null with an extra > qualifier is ugly and time-wasting. It is, nonetheless, the only backwards-compatible way to do this. It's just like "const" in that regard. "const" should have been the default; a different keyword should have been required for the less common case where a variable should be non-const - but by the time "const" was invented, there was already too much existing code which would have been broken by making it the default state. Note: your suggestion would NOT break existing code, but only because you define the consequences in terms of the issuing of a warning. That's a defect in your proposal. The standard, quite deliberately, does not deal with warnings - that's for implementations to worry about. The standard is for defining the behavior of correct code, and identifying incorrect code. Providing a way to declare that some pointers may have null values, and others may not, and making it undefined behavior to assign a null value to a pointer whose declaration indicates that it is not supposed to have them, would be a worthwhile thing to do. It would implicitly encourage implementations to issue such a warning when they can easily detect such cases. Without the undefined behavior, your proposal isn't very useful. It cannot, unfortunately, be made a constraint violation, for which a diagnostic would be mandatory, because in general it is not possible at compile time to rule out the possibility that a given pointer might be assigned a null value.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-01-29 02:24 +0000 |
| Message-ID | <878rhmulh2.fsf@bsb.me.uk> |
| In reply to | #169082 |
Christopher Bazley <cs99cjb@gmail.com> writes: > I've just submitted my paper n3089, “_Optional: a type qualifier to > indicate pointer nullability” to the WG14 committee. > > This is either the most important thing I've ever written or a waste > of a few months of research, design, prototyping and > testing. Obviously, I'm hoping that it isn't the latter, but I'm fully > prepared for that outcome! :) If you have time and interest in how to > improve the C programming language, then please read on. > > Abstract: This paper proposes a new type qualifier for the purpose of > adding pointer nullability information to C programs. Its goal is to > provide value not only for static analysis and documentation, but also > for compilers which report errors based only on existing > type-compatibility rules. The syntax and semantics are designed to be > as familiar (to C programmers) and ergonomic as possible. In contrast, > existing solutions are incompatible, confusing, error-prone, and > intrusive. > > I wrote a Medium article with much the same content as my paper, which > is published here: > https://medium.com/itnext/why-c-needs-a-new-type-qualifier-61ad553cbe71 I didn't read the actual committee paper (I would have done if you'd have linked to it) so I read this instead, and I really wanted it to be written the other way round! There's (virtual) pages of stuff before you get to the serious stuff. I gave up twice, but I went on later and I did get to the proposal but I was not reading in detail by that time. I wanted the details up top, but then I may not be in the intended audience for that blog post. Anyway, only one thought came to me by the end. Why is it & and not * that removes the new qualifier? It's the use of * that is asserting that the pointer is not null. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Christopher Bazley <cs99cjb@gmail.com> |
|---|---|
| Date | 2023-01-29 01:21 -0800 |
| Message-ID | <5941b114-ad10-4a13-8692-4a3760e8258cn@googlegroups.com> |
| In reply to | #169090 |
On Sunday, 29 January 2023 at 02:24:27 UTC, Ben Bacarisse wrote: > I didn't read the actual committee paper (I would have done if you'd > have linked to it) so I read this instead, and I really wanted it to be > written the other way round! There's (virtual) pages of stuff before > you get to the serious stuff. I gave up twice, but I went on later and > I did get to the proposal but I was not reading in detail by that time. > I wanted the details up top, but then I may not be in the intended > audience for that blog post. Hi Ben, So far I only shared the PDF of my paper with colleagues and the committee. Sorry that the style of the Medium article doesn't work for you. I suggest referring to my LLVM forum post instead, which is very like the submitted paper but with some additional details at the end about how I prototyped the new feature in Clang: https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ Unfortunately, I do think that "pages of stuff" are required to justify a novel solution to a longstanding problem that has had many previous attempted solutions. I did cut out a whole section exploring (and discarding) use of a new symbol. > Anyway, only one thought came to me by the end. Why is it & and not * > that removes the new qualifier? It's the use of * that is asserting > that the pointer is not null. I went back and forth on that question in the middle of the night for a few weeks. I thought I had explained my final decision adequately but maybe it got lost in the middle of the paper: > It’s tempting to think that the appropriate time to remove > a maybe-null qualifier from a pointer is the same moment > at which undefined behaviour would ensue if the pointer > were null. I prototyped a change to remove the _Optional > qualifier from the result of unary *, but found it onerous > to add &* everywhere it was necessary to remove the > _Optional qualifier from a pointer. > > Moreover, many previously simple expressions became > unreadable: > > &(&*s)[index] (instead of &s[index]) > &(&*s)->member (instead of &s->member) > > Whilst it would have been possible to improve > readability by using more intermediate variables, that > isn’t the frictionless experience I look for in a programming > language. (The same consideration applies to reliance on > casts in the absence of modified operator semantics.) I hope that helps. If not, let me know. Cheers, Christopher
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-01-29 13:35 +0000 |
| Message-ID | <87wn55tqep.fsf@bsb.me.uk> |
| In reply to | #169093 |
Christopher Bazley <cs99cjb@gmail.com> writes: > On Sunday, 29 January 2023 at 02:24:27 UTC, Ben Bacarisse wrote: >> I didn't read the actual committee paper (I would have done if you'd >> have linked to it) so I read this instead, and I really wanted it to be >> written the other way round! There's (virtual) pages of stuff before >> you get to the serious stuff. I gave up twice, but I went on later and >> I did get to the proposal but I was not reading in detail by that time. >> I wanted the details up top, but then I may not be in the intended >> audience for that blog post. > > Hi Ben, > > So far I only shared the PDF of my paper with colleagues and > the committee. Sorry that the style of the Medium article > doesn't work for you. > > I suggest referring to my LLVM forum post instead, which is very > like the submitted paper but with some additional details at the end > about how I prototyped the new feature in Clang: > https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ > > Unfortunately, I do think that "pages of stuff" are required to > justify a novel solution to a longstanding problem that has > had many previous attempted solutions. I did cut out a > whole section exploring (and discarding) use of a new symbol. I have no problem with the quantity, just the order! For a technical subject, I don't like the author pulling punches. The head line, that the qualifier is not on the pointer but the target type, would grab people's interest and distinguish your work for almost all the alternatives right away. Not everyone will know all the alternatives but that could come later. But I accept that the blog post is not intended for this sort of audience, but there was not other URL. >> Anyway, only one thought came to me by the end. Why is it & and not * >> that removes the new qualifier? It's the use of * that is asserting >> that the pointer is not null. > > I went back and forth on that question in the middle of the > night for a few weeks. I thought I had explained my final > decision adequately but maybe it got lost in the middle of > the paper: I was skimming by that time. I should have gone to the end where the proposal is presented and then read backwards. >> It’s tempting to think that the appropriate time to remove >> a maybe-null qualifier from a pointer is the same moment >> at which undefined behaviour would ensue if the pointer >> were null. I prototyped a change to remove the _Optional >> qualifier from the result of unary *, but found it onerous >> to add &* everywhere it was necessary to remove the >> _Optional qualifier from a pointer. >> >> Moreover, many previously simple expressions became >> unreadable: >> >> &(&*s)[index] (instead of &s[index]) >> &(&*s)->member (instead of &s->member) &s[i] includes a * operation by definition so &s[i] would (if the qualifier were removed by *) do the job of &(&*s)[i]. Maybe there are cases where one does not want &s[i] to be a pointer to an unqualified type. And although p->m is not /defined/ to mean (*p).m I was including it. I was wondering why it was & rather than either explicit or implicit indirection that removed the qualifier. >> Whilst it would have been possible to improve >> readability by using more intermediate variables, that >> isn’t the frictionless experience I look for in a programming >> language. (The same consideration applies to reliance on >> casts in the absence of modified operator semantics.) > > I hope that helps. If not, let me know. I'm just clarifying my rather abbreviated question, so if it's answered already I'll go look at the other material you suggested (time permitting). -- Ben.
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web