/*author: mike bell twitter: @therealdarkmagedate: Fri Aug 9 5:12 PMwebsite: https://mikebell.xyzI was playing around and discovered a weird way to perform a substring on a string in C++.Take the address of a string and then, using array indexing, add the position to substring from.Works with constant and arbitrary strings! Cool/weird!Compiles on current macOS g++ as of this writing.*/#include <iostream>#include <string>using std::string;using std::cout;using std::endl;int main() { string s = &"Hello, World"[7]; string ss = &s[2]; cout << s << endl; // prints "World" cout << ss << endl; // prints "rld" return 0;}
Top comments(4)

- Email
- LocationTime Vortex
- Pronounshe/him
- WorkAuthor of "Dead Simple Python" (No Starch Press)
- Joined
The second use,ss
, isn't particularly weird, actually.std::string
is basically a wrapper around a c-string (char
array).
A few things to consider:
C-strings are a linear data structure, stored in adjacent memory (as opposed to a list.)
C-strings have to end with the null terminator
\0
, which marks the end of the string. If a c-string lacked this, there would be no way to know when to stop; the actual length of a c-string is not stored anywhere. (Astd::string
might cache the length for efficiency reasons though. I haven't read implementation in a while, but I suspect it to be so.)Applying the
[]
operator to a pointer is just performing pointer arithmetic.&
before a variable name is returning the memory address of the variable. In the case ofstd::string
, the first thing in the object's memory is the internal c-string.
The "magic" is all happening onstring ss = &s[2];
...
We get the address of
s
, which also happens to point to the beginning of the c-string inside ofs
.[2]
is the same asaddress + 2
. That means you're pointing to the third character in memory now.The c-string is read starting at that pointer, and goes until it encounters the
\0
.Said c-string is passed to the constructor for
std::string
, and is used to createss
.
My only caution with this method is that it makes assumptions about the implementation details ofstd::string
. If you use another string class, it might not behave the same.
The safer way to do the same thing is to save the pointer to the c-string inside ofs
vias.c_str()
, andthen work with that pointer directly. And even then, you're still notas safe as if you just usedstd::string
's own member functions, because if you get your pointer arithmetic wrong, you're going to have memory errors.

- Email
- LocationSheffield, United Kingdom
- EducationSheffield Hallam University.
- Joined
A "fun" side effect of the fact that the C++ (and C) subscript operator is just pointer arithmetic means that
constchar*array[]={"Well","This","Is","Strange"};// value contains "Strange"constchar*value=(1+1)[array+1];
is actually valid C++ 😆.
Becausex [y]
is the same as*(x + y)
, that means that
constchar*x=(1+1)[array+1];
is just the same as
constchar*x=*(1+1+array+1);// Orconstchar*x=*(array+3);// array [3]
It's worth only noting that this works where the subscript operatordoes use pointer arithmetic (C style arrays and pointers mostly I think) and not where the[]
operator is overloaded - so you can't do
std::stringv="Hello World!";charsecond_letter=1[v];
So I guess that means the original example of
strings=&"Hello, World"[7];stringss=&s[2];
can be rewritten as
std::strings=&(2*3+1)["Hello, World!"-1];
if you were so inclined 😆.
Sometimes I worry about C++ - it doesn't exactly help itself at times... 😄
Obligatory godbolt for this:
godbolt.org/z/nHJOgs

- Email
- LocationTime Vortex
- Pronounshe/him
- WorkAuthor of "Dead Simple Python" (No Starch Press)
- Joined
Sometimes I worry about C++ - it doesn't exactly help itself at times... 😄
Yes, but at least we get to play with esoteric hackery without needing a different language.
...and sometimes,ever so rarely, if the stars are aligned, that hackery comes in handy.

- LocationTexas
- EducationBachelor's Degree
- WorkComputer Science Mentor at Freelance
- Joined
I knew about the pointer arithmetic aspect from college, but I had no idea you could also do it with string constants! Thank you for the explanation!
For further actions, you may consider blocking this person and/orreporting abuse