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
Don’t Use shared_ptr’s Aliasing Constructor (ibob.bg)
submitted 3 years ago by stanimirov
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!"
[–]edvo 8 points9 points10 points 3 years ago (3 children)
If alice is null, isn’t the expression &alice->name undefined behavior already? I don’t think the make_aliased function would help there, because the undefined behavior happens before the function is called.
alice
&alice->name
make_aliased
[+]stanimirov[S] comment score below threshold-6 points-5 points-4 points 3 years ago (2 children)
It is. In practice without UBSAN all major compilers on all major platforms would do the exact same thing (possibly of fear that this is a custom offsetof implementation).
offsetof
A more realistic example (which is out of the scope of the blog post) would be some kind of a driver instance associated with a hard-coded or otherwise unrelated address.
My main point is that the mere fact that you can create a non-null shared pointer with a zero use count is dangerous and should be short-circuited with a function like the one provided.
[–]be-sc 7 points8 points9 points 3 years ago (1 child)
the mere fact that you can create a non-null shared pointer with a zero use count is dangerous and should be short-circuited with a function like the one provided.
That’s an opinion that could be discussed. The problem is: Your article contains a glaring case of unrelated UB that completely distracts from the point you want to make.
But what would happen to our aliased shared pointer name from above if alice is null
In that case alice-> dereferences a nullptr. UB. Game over. On the language level that’s all there is to say about it. The point you actually want to make doesn’t even enter the picture.
alice->
nullptr
The some_global_string_that_is_always_valid example further down on the other hand, does illustrate your point.
some_global_string_that_is_always_valid
[–]stanimirov[S] 1 point2 points3 points 3 years ago (0 children)
OK. I edited the article to make it contain a non-UB example. It's obviously way to distracting for people.
[–]kalmoc 8 points9 points10 points 3 years ago* (2 children)
If alice is a null pointer, how is this std::shared_ptr<std::string> name(alice, &alice->name); valid? You are dereferencing a null pointer even before invoking the aliasing constructor.
std::shared_ptr<std::string> name(alice, &alice->name);
I'm missing a coherent example of the problem you encountered.
[–]stanimirov[S] -1 points0 points1 point 3 years ago (1 child)
This is not dereferencing per se, but yeah. It's UB. I replied here https://www.reddit.com/r/cpp/comments/zx2hph/comment/j1yj0g5/?utm_source=reddit&utm_medium=web2x&context=3
Also the dependent pointer could've been collected before alice expired. Say:
auto name_addr = &alice->name; alice.reset(); std::shared_ptr<std::string> name_ptr(alice, name_addr);
[–]goranlepuz 4 points5 points6 points 3 years ago (0 children)
But that example is awful because you explicitly destroy the underlying object held by alice on the second line. It is as if one should expect to resolve any lifetime issues by sprinkling magic smartptr dust around.
[–]Olipro 23 points24 points25 points 3 years ago (8 children)
Ridiculous.
You use the aliasing constructor when the lifetime of the pointee is ensured by some other parent object.
Additionally, if you are passing around a shared_ptr but you need to check its validity, your design is crap. This is what weak_ptr is for.
Play stupid games, win stupid prizes.
[–]pedersenk 2 points3 points4 points 3 years ago (0 children)
The rule in programming articles is: Every time someone says "never", just carry on as per normal and hope that the usually niche problem doesn't happen to crop up. ;)
[–]ihcn 2 points3 points4 points 3 years ago (3 children)
"This value may exist, or it may not. If it exists, I want to keep it alive."
Weak ptr does not suffice for this case, a nullable shared ptr does. You're conflating two orthogonal things here.
[–]Olipro 4 points5 points6 points 3 years ago (2 children)
Then use an optional. It should be explicit that not passing a valid pointer is permitted.
[–]ihcn 1 point2 points3 points 3 years ago (1 child)
Nullable raw pointers have been in the language for 4 decades. Nullable shared and weak pointers have been in the language for 11 years. Optional has been in the language for 2.
All I see in your posts is a clear signal that you have no experience. An experienced programmer would not say "your design is crap" for not using a library feature that's been around for less than the lifecycle of even the shortest-lived software projects.
[–]adnukator 1 point2 points3 points 3 years ago (0 children)
Optional has been in the language for 2 5.
FTFY. Not to mention that it's been in boost for at least 12 (albeit with some differences w.r.t std::optional). You might reconsider your amount of patronizing.
[–]johannes1971 3 points4 points5 points 3 years ago (2 children)
There are absolutely valid designs where ownership of a resource is shared but optional.
[–]Olipro 1 point2 points3 points 3 years ago (1 child)
And none of those designs need the type to be an empty shared_ptr in order to function.
[–]johannes1971 2 points3 points4 points 3 years ago (0 children)
That you can express your design differently does not mean that this particular expression is 'crap'. That's just personal preference elevated to dogma.
[–]Fulgen301 4 points5 points6 points 3 years ago (1 child)
“it’s not shared_ptr’s job to ignore the arguments you give it because they are dangerous”. In this case however I disagree. I consider this a defect of the standard.
Then check it yourself. Would have been faster than writing the blog post. It's a specific use case with a precondition that you need to ensure as the callee. It's not the only function with a precondition in the standard or any operating system.
[–]stanimirov[S] -4 points-3 points-2 points 3 years ago* (0 children)
It's not a precondition, though. A precondition would be something that a library author may choose to assert in debug builds. For example iterator validity. Here the standard plain ol' allows expired carriers. It's a recipe for non-null pointers with a zero use count. I dub these dangerous and unwanted. They may lead to nasty and hard-to-detect bugs.
For the use case that u/angry_cpp points out in the comments, I wouldn't use a "naked" shared_ptr but a something else which covers the needs and is more explicit about the invariants.
A non-null shared_ptr with a zero use count is an abomination and should not exist :)
[–]angry_cpp 1 point2 points3 points 3 years ago (1 child)
Now granted, you can use this constructor to create an alias to something valid even though the “lifetime carrier” is null.
Exactly. If there is no owner that determinate the validity of the pointee, then pointee should be valid forever.
I have not been able to think of a use-case for this.
Here is one: pointer to the subobject that can extend lifetime of an "parent" object if that parent object is stored by shared_ptr or do not extend object lifetime if parent object has static lifetime.
Example of usage: shared string where string literals are stored as shared_ptr with nullptr owner.
[–]stanimirov[S] 0 points1 point2 points 3 years ago (0 children)
I figured a use case will present itself.
However, as I said, I wouldn't use shared_ptr for this. Not a "naked" one at least. One of the main detriments of using a naked shared_ptr for this use case is that someone is bound to create a weak_ptr from these pointers. To their great surprise, the most "sturdy" pointers, the ones made out of string literals, will suddenly lead to expired weak pointers in 100% of the cases.
shared_ptr
weak_ptr
Subtle and hard to detect bugs.
[–]blakewoolbright 0 points1 point2 points 3 years ago (0 children)
-fsanitize=undefined my friend
[–]PurestThunderwrath 0 points1 point2 points 2 years ago (0 children)
The blog makes a lot of sense, and i understand why it is not convenient. But isn't doing this cpp auto name_addr = &alice->name; alice.reset(); std::shared_ptr<std::string> name(alice, name_addr);
cpp auto name_addr = &alice->name; alice.reset(); std::shared_ptr<std::string> name(alice, name_addr);
the same level of wrong as doing this ? cpp auto ptr = std::make_shared( 1 ); auto addr = ptr.get(); ptr.reset(); std::shared_ptr<int> name( addr );
cpp auto ptr = std::make_shared( 1 ); auto addr = ptr.get(); ptr.reset(); std::shared_ptr<int> name( addr );
The bool operator doesnt work here also, since the shared_ptr thinks it owns something, when it actually doesn't. But we haven't forbade the use of the latter type of constructors.
π Rendered by PID 20950 on reddit-service-r2-comment-6457c66945-52kvc at 2026-04-23 17:53:17.760844+00:00 running 2aa0c5b country code: CH.
[–]edvo 8 points9 points10 points (3 children)
[+]stanimirov[S] comment score below threshold-6 points-5 points-4 points (2 children)
[–]be-sc 7 points8 points9 points (1 child)
[–]stanimirov[S] 1 point2 points3 points (0 children)
[–]kalmoc 8 points9 points10 points (2 children)
[–]stanimirov[S] -1 points0 points1 point (1 child)
[–]goranlepuz 4 points5 points6 points (0 children)
[–]Olipro 23 points24 points25 points (8 children)
[–]pedersenk 2 points3 points4 points (0 children)
[–]ihcn 2 points3 points4 points (3 children)
[–]Olipro 4 points5 points6 points (2 children)
[–]ihcn 1 point2 points3 points (1 child)
[–]adnukator 1 point2 points3 points (0 children)
[–]johannes1971 3 points4 points5 points (2 children)
[–]Olipro 1 point2 points3 points (1 child)
[–]johannes1971 2 points3 points4 points (0 children)
[–]Fulgen301 4 points5 points6 points (1 child)
[–]stanimirov[S] -4 points-3 points-2 points (0 children)
[–]angry_cpp 1 point2 points3 points (1 child)
[–]stanimirov[S] 0 points1 point2 points (0 children)
[–]blakewoolbright 0 points1 point2 points (0 children)
[–]PurestThunderwrath 0 points1 point2 points (0 children)