Date: Tue, 18 Feb 2025 19:42:30 +0000
I'm not sure what the benefit is to throwing an exception here is. I can't imagine any situation in which you would write a case block specifically to handle the case that someone below you on the callstack tried to dereference a nullptr.
It would seem to me that if you're specifically annotating a series of pointer dereferences then you're stating that it's intentional that they might fail. In that case the correct thing to do is check them and throw a more descriptive exception when you see they're null. It's much easier to imagine someone catching a, say, SubsystemNotInitalised exception than a generic NullptrDereference exception. One provides a clear idea of what the problem is and how you might fix it, and the other one tells you nothing besides that the person who wrote a function below you on the callstack specifically thought that a deference might fail but declined to handle it in a meaningful way. Not providing a built-in easy way for people to thoughtlessly handle a error case that they really should think more deeply about is a feature of the standard in that way.
Unless of course you're envisioning it as a debugging feature, in which case I'd question the utility even more since things like UBSan and the general category of debuggers exist that can every easily catch nullptr dereferences without requiring that you also specifically annotate your pointer dereferences for them to be checked.
On 18 February 2025 15:39:48 GMT, Filip <fph2137_at_[hidden]> wrote:
>What if dereferencing nullptr would not be an undefined behavior?
>Maybe it could simply throw an exception that try could catch or like you mentioned: automatically rethrow.
>
>try would not be forced upon the programmer but any series of pointer access could be quickly and easily (like I would love to have) checked. Instead of try else, it would be try catch and a removal of UB?
>
>It could be enabled with a flag and using try on any expression would not be invalid but would work only with a flag.
>
>The type of this exception is puzzling me now, perhaps nullptr<yourPtrType> ?
>
>Cheers, Filip
>
>> Wiadomość napisana przez Jennifier Burnett via Std-Proposals <std-proposals_at_[hidden]> w dniu 17 lut 2025, o godz. 10:35:
>>
>>
>> Hi Filip,
>>
>> Like someone else said, the usual way this is done in other programming languages (swift/rust) is with a special ?. operator which short circuits the entire expression to null if the left hand side is null, so it would probably be better to match what other languages are already doing if possible so that people moving between c++ and other languages don't have to suddenly learn two different ways of doing the same thing. I believe GCC and Clang also already provide a non-standard extension ?: which returns the left hand side unchanged if it evaluates to true or else the right hand side (which is possibly more generally applicable than just pointers and closer to what you're suggesting with the else), so standardising that instead of adding new syntax would mean that people already familiar with that don't have to learn something new and we'd have two compilers supporting it immediately. There's also nothing stopping us from providing both of the above options.
>>
>> There also was (is? I'm not sure on the current status) an exception improvement paper floating around at one point that suggested annotating individual statements that could throw an exception with try like you're doing here rather than having a try block, which beyond clashing with your proposal also seems more natural to what I'd expect your examples to be doing. The only place the try keyword is used in the standard is related to exception handling, so using it as you are here to represent something mostly unrelated to exceptions (but still vaguely in the area of error handling so I see why you'd use it) is adding two completely different meanings to a single keyboard which if we could avoid would be preferable.
>>
>> The syntax of try else catch also could also be confusing for people coming from other languages where an else after a try usually indicates a block that is unconditionally executed if the try doesn't throw an exception.
>>
>> Definitely I think the core of what you're proposing has value and I think would be a nice ergonomic feature to have standardised in c++ (evidenced by that fact that multiple languages and two compilers already provide ways to do it!), I just think your proposed syntax isn't the way to go.
>>
>> Jennifier
>>
>>
>>> On 16 February 2025 16:52:48 GMT, Filip via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>> Hi everyone,
>>> I want to present to you possible new syntax that would allow for an easy improvement of both safety and user experience with any pointer/optional type.
>>>
>>> We usually need to check many times the validity of an object, which is done with an:
>>> if(wrapperType) // use wrapper
>>> I frequently use code like:
>>> return ptrType->get(0)->getParamsPtr()->getName();
>>>
>>> With multiple sub wrappers or returned pointers I would love to be simply to reuse try keyword in the following way:
>>>
>>> try return ptrType->optType.otherWrapper.value;
>>> else return defaultValue;
>>>
>>> In this example try keyword would check if every but last element is castable to bool, allows for an access with either . or ->
>>> Then it would cast element by element in this statement and only go to the next element when the cast would succeed and return true.
>>>
>>> Possibly single try could also be used with a function like:
>>> try ptrType->returnedFunc();
>>>
>>> The function would be executed only if pointer is not null.
>>> It could also allow for a bit more complex syntax with catches, however it would then expand the meaning to also catch exceptions:
>>>
>>> try return ptrType->value;
>>> else return defaultValue;
>>> catch (exception e) return exceptionValue;
>>>
>>> Equivalent to wrapping entire try else with try catch.
>>>
>>> Cheers, Filip
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
It would seem to me that if you're specifically annotating a series of pointer dereferences then you're stating that it's intentional that they might fail. In that case the correct thing to do is check them and throw a more descriptive exception when you see they're null. It's much easier to imagine someone catching a, say, SubsystemNotInitalised exception than a generic NullptrDereference exception. One provides a clear idea of what the problem is and how you might fix it, and the other one tells you nothing besides that the person who wrote a function below you on the callstack specifically thought that a deference might fail but declined to handle it in a meaningful way. Not providing a built-in easy way for people to thoughtlessly handle a error case that they really should think more deeply about is a feature of the standard in that way.
Unless of course you're envisioning it as a debugging feature, in which case I'd question the utility even more since things like UBSan and the general category of debuggers exist that can every easily catch nullptr dereferences without requiring that you also specifically annotate your pointer dereferences for them to be checked.
On 18 February 2025 15:39:48 GMT, Filip <fph2137_at_[hidden]> wrote:
>What if dereferencing nullptr would not be an undefined behavior?
>Maybe it could simply throw an exception that try could catch or like you mentioned: automatically rethrow.
>
>try would not be forced upon the programmer but any series of pointer access could be quickly and easily (like I would love to have) checked. Instead of try else, it would be try catch and a removal of UB?
>
>It could be enabled with a flag and using try on any expression would not be invalid but would work only with a flag.
>
>The type of this exception is puzzling me now, perhaps nullptr<yourPtrType> ?
>
>Cheers, Filip
>
>> Wiadomość napisana przez Jennifier Burnett via Std-Proposals <std-proposals_at_[hidden]> w dniu 17 lut 2025, o godz. 10:35:
>>
>>
>> Hi Filip,
>>
>> Like someone else said, the usual way this is done in other programming languages (swift/rust) is with a special ?. operator which short circuits the entire expression to null if the left hand side is null, so it would probably be better to match what other languages are already doing if possible so that people moving between c++ and other languages don't have to suddenly learn two different ways of doing the same thing. I believe GCC and Clang also already provide a non-standard extension ?: which returns the left hand side unchanged if it evaluates to true or else the right hand side (which is possibly more generally applicable than just pointers and closer to what you're suggesting with the else), so standardising that instead of adding new syntax would mean that people already familiar with that don't have to learn something new and we'd have two compilers supporting it immediately. There's also nothing stopping us from providing both of the above options.
>>
>> There also was (is? I'm not sure on the current status) an exception improvement paper floating around at one point that suggested annotating individual statements that could throw an exception with try like you're doing here rather than having a try block, which beyond clashing with your proposal also seems more natural to what I'd expect your examples to be doing. The only place the try keyword is used in the standard is related to exception handling, so using it as you are here to represent something mostly unrelated to exceptions (but still vaguely in the area of error handling so I see why you'd use it) is adding two completely different meanings to a single keyboard which if we could avoid would be preferable.
>>
>> The syntax of try else catch also could also be confusing for people coming from other languages where an else after a try usually indicates a block that is unconditionally executed if the try doesn't throw an exception.
>>
>> Definitely I think the core of what you're proposing has value and I think would be a nice ergonomic feature to have standardised in c++ (evidenced by that fact that multiple languages and two compilers already provide ways to do it!), I just think your proposed syntax isn't the way to go.
>>
>> Jennifier
>>
>>
>>> On 16 February 2025 16:52:48 GMT, Filip via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>> Hi everyone,
>>> I want to present to you possible new syntax that would allow for an easy improvement of both safety and user experience with any pointer/optional type.
>>>
>>> We usually need to check many times the validity of an object, which is done with an:
>>> if(wrapperType) // use wrapper
>>> I frequently use code like:
>>> return ptrType->get(0)->getParamsPtr()->getName();
>>>
>>> With multiple sub wrappers or returned pointers I would love to be simply to reuse try keyword in the following way:
>>>
>>> try return ptrType->optType.otherWrapper.value;
>>> else return defaultValue;
>>>
>>> In this example try keyword would check if every but last element is castable to bool, allows for an access with either . or ->
>>> Then it would cast element by element in this statement and only go to the next element when the cast would succeed and return true.
>>>
>>> Possibly single try could also be used with a function like:
>>> try ptrType->returnedFunc();
>>>
>>> The function would be executed only if pointer is not null.
>>> It could also allow for a bit more complex syntax with catches, however it would then expand the meaning to also catch exceptions:
>>>
>>> try return ptrType->value;
>>> else return defaultValue;
>>> catch (exception e) return exceptionValue;
>>>
>>> Equivalent to wrapping entire try else with try catch.
>>>
>>> Cheers, Filip
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-02-18 19:42:41