3 ms·
Here's an implementation of <experimental/observer_ptr> set for C++17 aka the world's dumbest (and most poorly named) smart pointer. https://github.com/martinm
by autoreleasepool 11y ago
Here's an implementation of <experimental/observer_ptr> set for C++17 aka the world's dumbest (and most poorly named) smart pointer.
https://github.com/martinmoene/observer-ptr/blob/master/include/nonstd/observer_ptr.h https://github.com/martinmoene/observer-ptr/blob/master/incl...
I'm using a modified version in a personal library. It throws an exception on a nullptr dereference. I'm not sharing that version here because A. it's not ready, and B. You're definitely a better programmer than me and I don't feel like getting totally shit on today :)
I thought the whole point of the "world dumbest smart pointer" was that it's automatically nullptr'd for you so it can't dangle. I'm looking forward to hear why this isn't true. I've actually been brooding over this perceived advantage of C++ for a while now.
- pcwalton 11y agostd::vector<std::string> strings; strings.push_back("Hello"); std::observer_ptr<std::string> p(&strings[0]); strings.clear(); std::cout << p; // use after free
- autoreleasepool 11y agoThat wouldn't compile. To use the header I linked it should be `nonstd::observer_ptr<std::string> p(&strings[0]);` You also need to dereference p to use the stream operator. I'm disappointed you presented such a contrived example. You also deliberately avoid const-correctness. That's a little insidious. You need to const everything manually in C++, so as a good C++ programmer you should const everything as you write C++. Only carefully omit const when you need mutability. We all know C++98 is dangerously unsafe. Let's write your example in C++11. #include <iostream> #include <string> #include <vector> #include <memory> #include <utility> #include "observer_ptr.h" // kill the noise using std::cout; using std::vector; using std::string; using nonstd::observer_ptr; int main() { vector<string const> const strings { "Hello" }; observer_ptr<string const> const p(&strings[0]); strings.clear(); // not gonna happen cout << *p; } » clang++ -std=c++11 immutable.cpp immutable.cpp:11:5: error: member function 'clear' not viable: 'this' argument has type 'const std::vector<const std::string>' (aka 'const vector<const basic_string<char, char_traits<char>, allocator<char> > >'), but function is not marked const strings.clear(); // not gonna happen ^~~~~~~ /usr/local/Cellar/llvm/HEAD/bin/../include/c++/v1/vector:735: 10: note: 'clear' declared here void clear() _NOEXCEPT ^ 1 error generated. EDIT: Down voted for legitimate rebuttal. Nice.
- oldmanjay 11y agoIt seems you're sort of missing a big point here. You demonstrate how, with sufficient vigilance, you can write safe C++. The goal of Rust is to move the vigilance into the language and make the unsafety opt-in rather than attempt-to-run-from.
- autoreleasepool 11y ago> with sufficient vigilance So now using const is some kind of difficult task? Not much cognitive overhead there. I thought everyone was onboard with immutability these days. My point is that safe low-overhead data structures with non-dangling, pointers protected from nullptr dereferencing ARE possible in C++ and not Rust. Yes, you have to put const after every type. Call that vigilance if you want. It's a really small price to pay IMO. Edit: Down voted again. What's wrong with my point or code? I'm curious.
- pcwalton 11y ago> So now using const is some kind of difficult task? Not much cognitive overhead there. I thought everyone was onboard with immutability these days. The fact that if you make everything totally immutable you can write safe C++ is (a) not true; (b) even if it were true, a totally irrelevant point in practice since not everything can be immutable. "C++ is memory-safe if you don't mutate anything anywhere" is a completely uninteresting point to the real world (even if it were true). > My point is that safe low-overhead data structures with non-dangling, pointers protected from nullptr dereferencing ARE possible in C++ and not Rust. Yes, you have to put const after every type. Call that vigilance if you want. It's a really small price to pay IMO. No, it's completely wrong. You have no protection from dangling references in C++.
- autoreleasepool 11y ago> No, it's completely wrong. You have no protection from dangling references in C++. I'd love to see an example without globals or an undefined behavior factory function.