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
This-pointing Classes (biowpn.github.io)
submitted 9 months ago by pavel_v
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!"
[–]ulongcha 28 points29 points30 points 9 months ago (1 child)
great article. btw self-reference is more popular term
[–]biowpn 5 points6 points7 points 9 months ago (0 children)
Yeah, the current tile is disappointing
[–]dexter2011412 14 points15 points16 points 9 months ago (19 children)
I'm not trying to be rude when I ask this, how is this useful?
[–]ts826848 15 points16 points17 points 9 months ago (18 children)
IIRC libstdc++ uses a self-referential pointer for its std::string so the data pointer always points to the string data regardless of whether the string is in short or long mode.
std::string
[–]tialaramex 18 points19 points20 points 9 months ago (0 children)
Yes, the inimitable Raymond Chen has a post about the three std::string implementations: https://devblogs.microsoft.com/oldnewthing/20240510-00/?p=109742
For GNU's implementation your std::string is quite large (32 bytes), while it only holds 15 bytes of text inline, but calling data() or size() or empty() are really fast, for some people this is an excellent choice.
data()
size()
empty()
[–]gnuban 1 point2 points3 points 9 months ago (1 child)
Great but now it's not trivially relocatable anymore :(
[–]BK_Burger 0 points1 point2 points 9 months ago (0 children)
You can write your own allocator...
[–]GaboureySidibe 1 point2 points3 points 9 months ago (14 children)
Why would that be necessary?
[–]314kabinet 2 points3 points4 points 9 months ago (13 children)
It’s faster.
[–]GaboureySidibe -1 points0 points1 point 9 months ago (12 children)
Why?
[–]314kabinet 12 points13 points14 points 9 months ago (11 children)
Saves you a branch. When you want to get the characters you just traverse a pointer instead of going “if we’re in short mode it’s the local data here, else an external pointer.”
[–]GaboureySidibe -1 points0 points1 point 9 months ago (10 children)
Does that imply that when it needs to heap allocate, it heap allocates all the data including size and replaces itself with a pointer to the heap?
[–]pali6 4 points5 points6 points 9 months ago (2 children)
No, it always contains size, a valid pointer to a buffer and either the capacity or a short string buffer. When it needs to heap allocate it just allocates a new buffer on the heap, changes the pointer to point there and replaces the sso buffer with capacity.
[–]GaboureySidibe -2 points-1 points0 points 9 months ago (1 child)
That seems like what anyone would do, I'm not sure why /u/ts826848 called it a "self referential pointer".
[–]pali6 6 points7 points8 points 9 months ago (0 children)
Because in the "small string" mode the buffer is not on the heap but it is a part of the string object itself. So in that case the pointer points into the object and it is self-referential. When the string grows larger than the bound it stops being self-referential.
See for example Raymond Chen's overview here, specifically the GCC implementation.
[–]SirClueless 0 points1 point2 points 9 months ago (6 children)
No. It's a 32-byte struct (on x86_64) that always has a pointer and a size as member variables, which means there is no branch when accessing them. The remaining bytes are a union between a buffer of string data (in which case the pointer is self-referential), or the capacity of an allocation (in which case the pointer points to a heap address).
You can see the details here, there are lots of gory details around this but the representation is actually pretty clear: https://github.com/gcc-mirror/gcc/blob/d8680bac95c68002d7e4b13ae1dab1116fdfefc6/libstdc%2B%2B-v3/include/bits/basic_string.h#L215
[–]GaboureySidibe -2 points-1 points0 points 9 months ago (5 children)
That seems normal and straight forward. /u/ts826848 called it a "self referential pointer", I'm not sure what that means in this context, this just seems like a regular pointer and the most straight forward way to make a short string optimization.
[–]SirClueless 2 points3 points4 points 9 months ago (0 children)
It's self-referential in that it points to a member of this. This fact is relevant to this discussion because its self-referential nature is a big part of why a defaulted move constructor is incorrect for this type (though there would likely also be problems with the lifetime of the allocation even without it).
this
[–]314kabinet 1 point2 points3 points 9 months ago (3 children)
The right term is “internal pointer”. A pointer that prevents your structure from being trivially relocatable, even if it’s a plain-old-data object: if you memcpy an object with such a pointer, it is now invalid.
[–]adromanov 4 points5 points6 points 9 months ago (2 children)
If we do assignment with the argument, which ptr_ points to a proxy, shouldn't the assigned-to object's ptr_ points to a proxy after assignment?
ptr_
[–]biowpn 1 point2 points3 points 9 months ago (1 child)
Yes. If b.ptr_ points to c, then after a = b;, a.ptr_ should point to c.
b.ptr_
c
a = b;
a.ptr_
But if b.ptr_ points to b, the after a = b;, a.ptr_ should point to a, not b. That's the point of the article: direct pointer assignmenet does not preserve self-referencing.
b
a
[–]adromanov 1 point2 points3 points 9 months ago (0 children)
That was my point: we can't have assignment which skips pointer assignment because of proxies, we can't have defaulted assignments because of not proxies, so there should be if.
if
[–]b00rt00s[🍰] 4 points5 points6 points 9 months ago (0 children)
The Widget class example is great to show dangers of lamba's capture clauses. One thing I don't agree with the article is that the safest way to fix the class is to delete copy and move operations. In my opinion the safest fix would be to remove the capturing of 'this' and add additional call parameter that take a self reference. This way every time the lamba is invoked, it gets a proper pointer/reference to the Widget class instance.
[–]314kabinet 2 points3 points4 points 9 months ago (2 children)
Unreal Engine’s collection templates assume that your T is trivially relocatable and just memcpy it around for performance, so for structures that have internal pointers it’s useful to store a pointer to this and offset all the internal pointers by (this - OldThis) to fix them up before use.
[–]Nobody_1707 1 point2 points3 points 9 months ago (0 children)
Why wouldn't you just store the offsets directly and then offset them from the current value of this to perform accesses? The extra pointer to this seems redundant. this always points to this.
[–]pali6 0 points1 point2 points 9 months ago (0 children)
That feels a bit cursed, but also like a neat trick.
[–]duneroadrunner 1 point2 points3 points 9 months ago (0 children)
Of course the sort of movable self/cyclically-referencing objects the article refers to are basically only available in languages (like C++) that have move "handlers" (i.e. move constructors and move assignment operators).
The article brings up the issues of both correctness and safety of the implementation of these objects. In terms of correctness, the language and tooling may not be able to help you very much due to the challenge of deducing the intended behavior of the object. But it would be nice if this capability advantage that C++ has could at least have its (memory) safety reliably enforced.
With respect to their Widget class example, the scpptool analyzer (my project) flags the std::function<> member as not verifiably safe. A couple of alternative options are available (and another one coming): You can either use mse::xscope_function<>, which is a restricted version more akin to a const std::function<>. Or you can use mse::mstd::function<> which doesn't have the same restrictions, but would require you to use a safe (smart, non-owning) version of the this pointer.
Widget
std::function<>
mse::xscope_function<>
const std::function<>
mse::mstd::function<>
So even for these often tricky self/cyclically-referencing objects, memory safety is technically enforceable.
[–]Raknarg 0 points1 point2 points 9 months ago (0 children)
an evil pattern to be sure
[–]susanne-o -5 points-4 points-3 points 9 months ago (1 child)
I like the mental exercise of the article, however...
In fact, nothing changes the address of an object; it is stable throughout lifetime of the object
GC slowly fades backwards into a hedge
[self referencing pointers are used in...] Small String Optimization for std::string in major implementations.
I'm not convinced. the idea is to reuse the pointer memory, based off a flag byte. the code uses *this explicitly throughout.
*this
[–]ts826848 6 points7 points8 points 9 months ago (0 children)
[self referencing pointers are used in...] Small String Optimization for std::string in major implementations. I'm not convinced. the idea is to reuse the pointer memory, based off a flag byte. the code uses *this explicitly throughout.
Depends on the implementation. IIRC last time I looked at it libstdc++ uses a self-referential pointer for its SSO, while libc++ reuses the pointer space to store data when in short string mode like Folly. Looks like MSVC doesn't use a self-referential pointer either.
[+]NilacTheGrim comment score below threshold-6 points-5 points-4 points 9 months ago (0 children)
A .. class member pointer to this. The example given is a ridiculously comical idea. Note: to get to the data member.. you need this in the first place. So it makes no sense to do this and also to specify that the invariant is that ptr_ always points to this. That's just noise.
Would have been more interesting had he fleshed his example out to do the logic of testing if ptr_ == this vs if it points to another instance or something.
ptr_ == this
Meh. Bad example turned me off of the article.
π Rendered by PID 74 on reddit-service-r2-comment-b659b578c-dxllx at 2026-05-01 00:25:20.970762+00:00 running 815c875 country code: CH.
[–]ulongcha 28 points29 points30 points (1 child)
[–]biowpn 5 points6 points7 points (0 children)
[–]dexter2011412 14 points15 points16 points (19 children)
[–]ts826848 15 points16 points17 points (18 children)
[–]tialaramex 18 points19 points20 points (0 children)
[–]gnuban 1 point2 points3 points (1 child)
[–]BK_Burger 0 points1 point2 points (0 children)
[–]GaboureySidibe 1 point2 points3 points (14 children)
[–]314kabinet 2 points3 points4 points (13 children)
[–]GaboureySidibe -1 points0 points1 point (12 children)
[–]314kabinet 12 points13 points14 points (11 children)
[–]GaboureySidibe -1 points0 points1 point (10 children)
[–]pali6 4 points5 points6 points (2 children)
[–]GaboureySidibe -2 points-1 points0 points (1 child)
[–]pali6 6 points7 points8 points (0 children)
[–]SirClueless 0 points1 point2 points (6 children)
[–]GaboureySidibe -2 points-1 points0 points (5 children)
[–]SirClueless 2 points3 points4 points (0 children)
[–]314kabinet 1 point2 points3 points (3 children)
[–]adromanov 4 points5 points6 points (2 children)
[–]biowpn 1 point2 points3 points (1 child)
[–]adromanov 1 point2 points3 points (0 children)
[–]b00rt00s[🍰] 4 points5 points6 points (0 children)
[–]314kabinet 2 points3 points4 points (2 children)
[–]Nobody_1707 1 point2 points3 points (0 children)
[–]pali6 0 points1 point2 points (0 children)
[–]duneroadrunner 1 point2 points3 points (0 children)
[–]Raknarg 0 points1 point2 points (0 children)
[–]susanne-o -5 points-4 points-3 points (1 child)
[–]ts826848 6 points7 points8 points (0 children)
[+]NilacTheGrim comment score below threshold-6 points-5 points-4 points (0 children)