4 ms·
The standard way of dereferencing std::optional is with .value() and that does provide a check and an exception. Using * and -> is equivalent to invoking "unsaf
by zik 8y ago
The standard way of dereferencing std::optional is with .value() and that does provide a check and an exception. Using * and -> is equivalent to invoking "unsafe" in other languages. You get the semantics you ask for. If you don't want unsafe behaviour it's really as simple as using the safe operator. I don't honestly see what the problem is here.
- Gaelan 8y ago(Disclaimer: not a C++ programmer) I think the difference is that * and -> are normal things to do on a value. Other smart pointers also overload those operators, so it isn't an obvious red flag. For example, look at this code: foo()->bar() Is this safe? Depends on whether foo() returns a non-nullable smart pointer (or a raw pointer) or an std::optional. It doesn't raise any red flags when you're reading the code, and you can mess it up if you forget the signature. Sure, you could look at the signature of foo, but at that point you're looking at foo anyway and a doc comment telling you it was nullable would work just as well. (OK, it's slightly worse because you have to look at the comment. But you still have to look at the function to know what you're doing is safe.) On the other hand, in most other languages with optionals, you have something like this (Rust): foo().unwrap().bar() unwrap() is only used with optionals, so anyone reading the code knows this is something that might be a bug. If you forget that foo() returns an optional, you'd write foo().bar() instead, and you'd get a compiler error. The point of optionals, to me, is to have the compiler remind you to check nulls. If you can deref an optional in the same way that you deref a normal pointer, you don't get any of the benefits of optionals. (I guess it gives you a way to indicate null in places where you previously couldn't, which is useful but not why most people want optionals.)
- furgooswft13 8y agoThis is just standard C++isms. You can get a reference to an item in a std::vector with the [] operator as you would with an array in many other languages. It does not do bounds checking, as specified in documentation. Trying to access an out of range element is undefined behavior. Or you can use the .at() method, which will throw an exception if you go out of bounds. It is the programmer's choice. Bounds checking is not free, same with checking for a null pointer. C++ is a performance oriented language so it gives you the choice to play it a little unsafe in the name of having full control. I understand the idea to want the language to make it more obvious that you are doing something potentially unsafe, but it has never been the case in C or C++ that dereferencing a pointer is considered 'safe'. You have to know what you are doing, else you might end up blowing your whole leg off [1]. [1] https://www.goodreads.com/quotes/226222-c-makes-it-easy-to-shoot-yourself-in-the-foot https://www.goodreads.com/quotes/226222-c-makes-it-easy-to-s...
- Gaelan 8y agoI guess I don't know why you'd even want an optional if it wasn't for the safety. Without compiler-enforced null checking, I don't see why you'd want one.
- furgooswft13 8y agoC++ already has compiler-enforced null checking by virtue of not allowing non-pointer variables to be null. But sometimes we want a variable to be null and not be a pointer. Consider: struct stuff { int required_value; int optional_value; } What would you do if you had no value for optional_value? Probably use 0 or -1 but that can be problematic, and not even an option if optional_value is not a primitive type. You could use int* optional_value instead and just assign NULL, but then you have to malloc/new and make sure to free/delete later. You could use std::unique_ptr to handle memory management but you are still invoking dynamic memory. std::optional allows you to have nullable variables without using pointers, even when hidden behind the scenes. You could ask, what is the point of optional if you don't want to check if it is null? Well...I guess it's the same as no bounds checking, sometimes the programmer just knows. Most of the time, hopefully, a check will be done at some point, and subsequent accesses can skip the check.
- Gaelan 8y agoSo I guess C++'s optional type is for a completely different purpose from other languages, which is why I think I was confused.