Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

darkmage
darkmage

Posted on

     

A Weird Way to Substring in C++

/*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)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
codemouse92 profile image
Jason C. McDonald
Author. Speaker. Time Lord. (Views are my own)
  • Email
  • Location
    Time Vortex
  • Pronouns
    he/him
  • Work
    Author of "Dead Simple Python" (No Starch Press)
  • Joined
• Edited on• Edited

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];...

  1. We get the address ofs, which also happens to point to the beginning of the c-string inside ofs.

  2. [2] is the same asaddress + 2. That means you're pointing to the third character in memory now.

  3. The c-string is read starting at that pointer, and goes until it encounters the\0.

  4. Said c-string is passed to the constructor forstd::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.

CollapseExpand
 
barney_wilks profile image
Barney Wilks
2nd year Computer science student at Sheffield Hallam University - compiler nerd, fan of all things low level.

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

CollapseExpand
 
codemouse92 profile image
Jason C. McDonald
Author. Speaker. Time Lord. (Views are my own)
  • Email
  • Location
    Time Vortex
  • Pronouns
    he/him
  • Work
    Author 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.

CollapseExpand
 
therealdarkmage profile image
darkmage
Computer Science Tutor, Programmer, Gamedev, Hacker, Bug Bounty Hunter
  • Location
    Texas
  • Education
    Bachelor's Degree
  • Work
    Computer 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!

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Computer Science Tutor, Programmer, Gamedev, Hacker, Bug Bounty Hunter
  • Location
    Texas
  • Education
    Bachelor's Degree
  • Work
    Computer Science Mentor at Freelance
  • Joined

More fromdarkmage

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp