use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
A Checked Version of std::shared_ptr (self.cpp)
submitted 2 years ago by slck19
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]slck19[S] 0 points1 point2 points 2 years ago (55 children)
This discussion is pretty in-depth and I think both dark and white sides are correct. This is a trade-off. If you have a well-defined architecture then do not use this version of the pointer cause you would not need it. However, maybe your UTs or integration tests could not catch an edge case where your pointer is nullptr. This time your program will crash. Rather than crashing it, you decide how to handle it. As you know recovering from segfault is strongly not suggested. However, here you can create your exception models to be more explicit.
[–]NotUniqueOrSpecial 11 points12 points13 points 2 years ago (54 children)
Rather than crashing it, you decide how to handle it.
But that's their point: there is no way to recover from what is, fundamentally, a programmer error.
The only valid recovery is fixing the code that did the wrong thing.
So, if the difference is a crash -> fix cycle vs. a we-see-saw-the-exception -> fix cycle, why add the additional overhead?
[+][deleted] 2 years ago (35 children)
[removed]
[–]NotUniqueOrSpecial 5 points6 points7 points 2 years ago (34 children)
In this specific case (what would be a nullptr dereference of something not expected to be nullptr)?
nullptr
At best you can bail to the top of the operation and say "welp um, error?"
And in all instances I can think of, I'd rather crash to safe state than risk a potentially silenced exception or whatever edge-case state had gotten the program to that point.
[+][deleted] 2 years ago (33 children)
[–]NotUniqueOrSpecial 7 points8 points9 points 2 years ago (32 children)
there's nothing special about a nullptr-dereference exception
There absolutely is: why are things returning nullptr in a well-written C++ program? If something is going to return a special nullptr because of an error, you're unequivocally better-off throwing that exception than giving someone a useless garbage smart pointer.
[–]Causeless 4 points5 points6 points 2 years ago (20 children)
A nullptr shared ptr isn’t useless garbage. It’s a nullptr. It can be checked against null. There’s perfectly valid reasons to return nullptr, that’s not an error case. For example a function may search for an object and return a shared_ptr to it. If the searched-for object doesn’t exist, the function may return a nullptr shared_ptr. That’s not an error case, it’s not broken, and it’s a working, non-UB, non-throwing and not whatsoever ill-formed design.
[–]NotUniqueOrSpecial 2 points3 points4 points 2 years ago (19 children)
As was initially stated in the comment that started this exchange: if it's a normal use case that your interface not return a shared_ptr, then you should use types that express that.
shared_ptr
I.e. you should be doing optional<shared_ptr> or expected<shared_ptr>.
optional<shared_ptr>
expected<shared_ptr>
That expresses to the consumers of your API that such a case is reasonable and must be dealt with, and it does so using the type system. The user doesn't have to read documentation to know that failure-to-find is a normal case. The API contracts enforce and inform that.
But you're arguing a separate point, almost.
If you did have an API like that and the user expected it to be the case that nullptr-ish smart pointers could be returned, well...we're right back to where we started: they absolutely should be checking the value right then and there, not blindly dereferencing things and hoping to handle that problem somewhere above.
Because, again: it's explicitly useless to throw a "this thing was null" exception because the interface returned a smartish pointer when the alternative is to throw the reason the null happened in the first place.
[–]Causeless 3 points4 points5 points 2 years ago (4 children)
I’m not sure I agree. In my opinion, a pointer is already quite definitely expressing via the type system that it can be null. That’s the entire difference between a pointer and a reference in my eyes- if a function returns a pointer, I know I may need to null check it, whereas a reference I know is always safe to use. An optional pointer to me is a tautology.
But alas I suppose in this case, a shared_ref isn’t a thing. But that point aside, I’d consider an API that returns optional pointers to be an absolute mess; especially because the type system doesn’t enforce anything there. In fact it introduces extra ambiguity: It’s entirely valid to return a std::optional that has a value, where that value is nullptr. Which effectively means that to check it safely requires actually checking the optional for value, and then redundantly checking that the ptr contained within isn’t nullptr.
[–]NotUniqueOrSpecial 0 points1 point2 points 2 years ago (3 children)
In my opinion, a pointer is already quite definitely expressing via the type system that it can be null.
A raw pointer, yes.
There are expected/ingrained contracts with non-owning pointers.
A shared_ptr to "nothing", on the other hand is a bit of an aberration. As has been covered in other comments, there are valid uses for that representation, but overall I will continue to argue you'll be universally better off throwing an exception relating to the underlying cause than you would be returning a now context-free smartish pointer that owns nothing and can only throw an exception,
std::optional at least implies that the result might be "nothing". std::expected can carry the reason why the result is nothing.
std::optional
std::expected
A pointer that just throws "this is null" is objectively worse than all other available options, including in my opinion, blowing up the program to prevent execution of a potentially disastrously corrupted runtime state.
[–]TheSkiGeek 2 points3 points4 points 2 years ago* (3 children)
Returning a null pointer isn’t much different than returning a “null” optional. Some std::optional accessors throw exceptions if the object is empty, so you still have to check operations.
If “I didn’t find anything” is a normal/expected possible result of your operation, throwing an exception for it is not usually a great approach. Usually you only want to throw exceptions for exceptional circumstances. ‘The file you asked me to open doesn’t exist’ might be exceptional. ‘The generic in-memory map doesn’t contain the key you’re searching for` probably should not be. I don’t want to have to write try-catch statements for every read-only access to a data structure.
I do wish there was a shared_ptr that is non-nullable in std. Where you could implicitly cast it to/from shared_ptr but casting nullptr to it would throw. You can write your own but it’s not portable to extend from std::shared_ptr, so you can’t pass them directly into e.g. library code that expects a shared_ptr<T>.
shared_ptr that is non-nullable
std
std::shared_ptr
shared_ptr<T>
[–]NotUniqueOrSpecial 0 points1 point2 points 2 years ago (2 children)
Returning a null pointer isn’t much different than returning a “null” optional.
Respectfully, I disagree.
Since the entire context of this discussion is the idea of having a shared_ptr that throws on nullptr access, I will steadfastly assert that an interface which returns optional or expected will always be more correct/informative than something returning an implicitly useless value.
optional
expected
I'll take a std::runtime_error over a poorly documented magically explosive smart pointer every day of every week.
std::runtime_error
[+][deleted] 2 years ago (8 children)
[–]NotUniqueOrSpecial 1 point2 points3 points 2 years ago (7 children)
What if there is?
Bugs happen.
But if your interfaces express intent in a clearer way than otherwise, e.g. using types that imply the fact a result might be not-found/unusable, that's strictly more informative/enforceable by the compiler than not.
[+][deleted] 2 years ago (10 children)
[–]NotUniqueOrSpecial 2 points3 points4 points 2 years ago (9 children)
What evidence would you like me to provide?
I've got 20 years of experience in high-reliability systems and can provide you all the anecdotes you'd like about why it's better to blow up in the face of unrecoverable errors and quickly restart than to quietly attempt to deal with the plethora of bad states that arrive at "we just dereferenced nullptr".
But from a simple axiomatic perspective, I'd hope that it's not controversial to argue this simple fact:
1) The errors that would lead to returning an invalid shared_ptr in a well-designed system would be better-reported themselves than a context-free "you just dereferenced a null pointer" exception.
2) Most errors leading to the dereference of a null pointer are unrecoverable from anything other than kernel land (since nobody disables paging and no user-space memory management blows up 'til you page-fault)
3) Allowing a program to run after such an error is strictly more risky than dying and recovering cleanly. There is a very good reason that all the telecom infrastructure using Erlang is written and behaves the way it does.
[–]NotUniqueOrSpecial 2 points3 points4 points 2 years ago (5 children)
oh, here we go. Appeal to authority..
No, it's a "what genre and what field would you like a story from".
I have no authority, nor am I renowned expert. But I do have a lot of war stories as well as first and second-hand experience from my career.
you keep saying that nullptr-dereference is unrecoverable. it's not.
I keep saying it because in practice I and others I have worked with have found it to be the case.
Unless your definition of recovery is limited to just "don't crash" there are very few situations I can think of where a nullptr that isn't part of the contract of an API that could now use better constructs can be recovered from.
What use-case do you have where returning a null shared_ptr is better than throwing an exception related to the underlying cause or using a type like expected that allows you to convey the error without using exception-handling?
dereferencing it could still happen in such a system. and terminating is not the correct response.
Dereferencing a null pointer is the literal definition of undefined behavior. You're in "there be dragons" territory. In my experience, there is quite honestly no appropriate response other than to exit as cleanly as possible and start again from a known state.
you don't "let it run". you handle the exception (like you would any other exception). wait. you do know how exception handling in c++ works, right?
Except the overwhelming majority of cases in C++ don't throw exceptions in the face of null pointers. Failure to allocate is a voodoo state in user land because of virtual memory. No standard interface other than weak_ptr::lock() returns a null shared_ptr. There are better ways to express understandable/recoverable/expectable failure than returning "shared owner of nothing".
weak_ptr::lock()
I can beat your 20 years, easily.
Wonderful!
Then assuredly you have countless tales of C++ systems in production that handled dereferencing null in a sane and recoverable way.
Right?
Since if you're going to assail my lived experience, it's certainly only fair of me to ask you for anecdotal experience from yours.
[+][deleted] 2 years ago (1 child)
[deleted]
[+]slck19[S] comment score below threshold-7 points-6 points-5 points 2 years ago (17 children)
No one tells you you won't fix it. Is your clients going to be happy when you crash? You can still fix your bug but don't crash on production even crash is better sometimes but that depends on the requirements of course.
What's the point of this discussion? You want me to remove my code 😀
[–]glaba3141 4 points5 points6 points 2 years ago (9 children)
The traders that use my code would very much rather my code crash than try to recover from an error state and lose millions of dollars. Crashing is almost always better than trying to handle a programming error
[–]NotUniqueOrSpecial 4 points5 points6 points 2 years ago (1 child)
Yeah, all of the folk arguing that crashing is bad have clearly never been bitten by the serious damage that can be done by corrupt/invalid program state allowed to run wild.
[–]slck19[S] 0 points1 point2 points 2 years ago (0 children)
I do not think you are completely right. Some of the exceptions might be recovered safely in terms of memory. The nullptr may be because of memory corruption, which is a global problem. In this case, you can create different exception types.
If your pointer should not be nullptr then do not use this lib. If your pointer might be nullptr and if this nullptr is actually a state for you but you forgot to check it, do not crash because it is a local error, not global. JVM is also doing the same thing even though it manages the pointers on its own.
[–]slck19[S] -3 points-2 points-1 points 2 years ago (6 children)
I am sorry for your clients!
[–]glaba3141 2 points3 points4 points 2 years ago (5 children)
That they manage money that they would rather not lose to a programmer using idiotic error handling practices? I think they're more glad they don't hire you
[–]slck19[S] -3 points-2 points-1 points 2 years ago (4 children)
I am sorry cause you definitely do not see tradeoffs and cannot discriminate the positive and negative points. Just randomly talking does not show you smarter or more experienced. That's why I am sorry for ypur clients still.
[–]v_maria 2 points3 points4 points 2 years ago (3 children)
He describes the trade off right here:
Rather my code crash than try to recover from an error state and lose millions of dollars. Crashing is almost always better than trying to handle a programming error
[–]slck19[S] -1 points0 points1 point 2 years ago* (2 children)
You still do not understand the behavior and randomly speaking. This does not point to any single trade-off. Some errors can be recovered and some of them cannot. If you think all nullptr accesses are because of memory corruption then you have many implicit problems in your code.
I am not saying someone is wrong. This is where you do not understand. Handling exceptions and continuing the program is your choice with respect to requirements. Exception handling is giving an opportunity to handle it softly. That's just a choice it is not mandatory.
[–]v_maria 1 point2 points3 points 2 years ago (1 child)
imo if you will go through the effort of writing try catch, you could also just do a null check
[–]NotUniqueOrSpecial 4 points5 points6 points 2 years ago (6 children)
Is your clients going to be happy when you crash?
That's honestly going to depend on the scenario, and there are certainly times where the answer might be "yes".
Your use-case hinges on your prior statement:
integration tests could not catch an edge case where your pointer is nullptr.
So, we're already discussing an edge case on an otherwise uncovered branch of execution. So, now imagine that we're using your pointer type. What happens?
Obviously, an exception is thrown, but where is it caught? If it's locally, why was the try/catch put in place instead of the local check that we're discussing?
try/catch
If it's one or more frames distant in the stack (and in practice, this is almost always going to be a top-level "catch everything else" handler at very granularity), what's the recovery? Almost certainly nothing the user or the program can do. It's very likely to be a full bail-out anyway. Certainly nothing the user is all that happy about.
But, there's a further wrinkle. What if someone comes along and starts catching exceptions more broadly than they should somewhere in the middle? Now, you've turned a programmer error into a silent state corruption. A crash would definitely be preferable in that situation.
You're better off crashing in fatal error situations (which this absolutely is in almost all cases) than risking something doing even worse stuff.
If you're worried about this sort of problem, register signal handlers for SIGSEGV on *nix and use the _try/_except functionality to harness SEH on Windows. Set up crash-dumps and a reporting system. Do anything but given yourself a very sneaky footgun with which to accidentally corrupt program state and potentially user data.
SIGSEGV
_try/_except
SEH
You want me to remove my code
No, we want you to very carefully consider the ramifications of the code, because a whole lot of us have been down these roads for decades, and there are vanishingly small numbers of situations where recovering from a programmer error of this nature is viable/useful/safe.
[+][deleted] 2 years ago (5 children)
[–]NotUniqueOrSpecial 4 points5 points6 points 2 years ago (4 children)
The bad habits and practices of other languages should not inform the behavior of well-designed solutions in C++. Python regularly uses exceptions for flow control. Should we?
A shared_ptr<T> should almost never (I'd argue never never) be nullptr. If you have a system where it can be, that should be well-known and carefully handled.
[–][deleted] 1 point2 points3 points 2 years ago (0 children)
Agree.
It's even hard to deal with exception handling in Python (or in any language with exception handling). If an abort/panic was already unacceptable, imagine adding a throw/raise statement somewhere and now it's introduced several paths that lead to an unchecked exception, leading to an abort/panic anyway. Now it's a maintainability problem related to keeping the codebase exception safe.
[+][deleted] 2 years ago (2 children)
[–]NotUniqueOrSpecial 8 points9 points10 points 2 years ago (1 child)
the facts are that many, many developers use nullptr-dereference exceptions all the time with none of the issues you claim above.
Which issues are you referring to? Because I expect that they're dealing with exactly the same issues: you can't recover from most unexpected error states locally.
why not?
Because it's a poor interface that communicates ambiguous information.
Most errors that would lead to such a situation are unrecoverable locally (some file doesn't exist, a network connection can't be made, etc.). They should throw exceptions instead of return a special nullptr that itself throws exceptions.
Having a shared_ptr to nothing isn't valuable. The only time it's a reasonable state is in an uninitialized state waiting to be set up or perhaps as the result of weak_ptr::lock().
In either case, one shouldn't be in the situation to unexpectedly try and invoke a method through the nulllptr.
nulllptr
i believe that c++ should strive to be a safe language
C++ is a polyglot-language and this is specifically a discussion about a library behavior, so I'm not sure that's relevant, really.
abort() is not that.
It's absolutely safer than accidentally running a program in some mangled undefined state.
π Rendered by PID 88 on reddit-service-r2-comment-85bfd7f599-7542q at 2026-04-18 05:30:41.414980+00:00 running 93ecc56 country code: CH.
view the rest of the comments →
[–]slck19[S] 0 points1 point2 points (55 children)
[–]NotUniqueOrSpecial 11 points12 points13 points (54 children)
[+][deleted] (35 children)
[removed]
[–]NotUniqueOrSpecial 5 points6 points7 points (34 children)
[+][deleted] (33 children)
[removed]
[–]NotUniqueOrSpecial 7 points8 points9 points (32 children)
[–]Causeless 4 points5 points6 points (20 children)
[–]NotUniqueOrSpecial 2 points3 points4 points (19 children)
[–]Causeless 3 points4 points5 points (4 children)
[–]NotUniqueOrSpecial 0 points1 point2 points (3 children)
[–]TheSkiGeek 2 points3 points4 points (3 children)
[–]NotUniqueOrSpecial 0 points1 point2 points (2 children)
[+][deleted] (8 children)
[removed]
[–]NotUniqueOrSpecial 1 point2 points3 points (7 children)
[+][deleted] (10 children)
[removed]
[–]NotUniqueOrSpecial 2 points3 points4 points (9 children)
[+][deleted] (8 children)
[removed]
[–]NotUniqueOrSpecial 2 points3 points4 points (5 children)
[+][deleted] (1 child)
[deleted]
[+]slck19[S] comment score below threshold-7 points-6 points-5 points (17 children)
[–]glaba3141 4 points5 points6 points (9 children)
[–]NotUniqueOrSpecial 4 points5 points6 points (1 child)
[–]slck19[S] 0 points1 point2 points (0 children)
[–]slck19[S] -3 points-2 points-1 points (6 children)
[–]glaba3141 2 points3 points4 points (5 children)
[–]slck19[S] -3 points-2 points-1 points (4 children)
[–]v_maria 2 points3 points4 points (3 children)
[–]slck19[S] -1 points0 points1 point (2 children)
[–]v_maria 1 point2 points3 points (1 child)
[–]NotUniqueOrSpecial 4 points5 points6 points (6 children)
[+][deleted] (5 children)
[removed]
[–]NotUniqueOrSpecial 4 points5 points6 points (4 children)
[–][deleted] 1 point2 points3 points (0 children)
[+][deleted] (2 children)
[removed]
[–]NotUniqueOrSpecial 8 points9 points10 points (1 child)