C/C++ Does VS support string_view in C++?

  • Thread starter Thread starter yungman
  • Start date Start date
  • Tags Tags
    Support
AI Thread Summary
Visual Studio 2019 requires specific compiler settings to recognize C++17 features like `string_view`. Users need to set the compiler option to `/std:c++17` in the project properties to compile code using `string_view`. A user initially faced issues with their code, which was resolved after adjusting these settings. Additionally, there were discussions about returning C-strings from functions, highlighting the importance of understanding pointers and return types in C++. The conversation emphasizes the need for clarity in error reporting and understanding basic concepts in C++.
yungman
Messages
5,741
Reaction score
294
I am playing with string_view which is C++17, I have VS-2019, it doesn't seem to recognize string_view. I cannot even troubleshoot my program:
C++:
#include <iostream>
#include <string>
#include <string_view>
using namespace std;
int main()
{
    string_view text = "Hello";
    string_view str(text);
    string_view more(str);
    cout << text << " " << str << " " << more << "\n\n";
    return 0;
}
Thanks.
 
Last edited by a moderator:
Technology news on Phys.org
jedishrfu said:
Here’s a write up on it

https://www.modernescpp.com/index.php/c-17-avoid-copying-with-std-string-view

From the examples, it appears that you missing some prefix stuff when using it. The examples use std:: in front of the string_view usage.
Thanks, I know there must be something wrong with the code. So it's just me, VS is not the issue?

Thanks
 
jedishrfu said:
it appears that you missing some prefix stuff when using it. The examples use std:: in front of the string_view usage.

His code has "using namespace std", which takes care of it.

However, he doesn't tell us what the error message is, which I think should be the bare minimum for a "debug my code" thread.
 
  • Like
Likes jedishrfu
Here's what I did, and I'm running VS 2017.
  1. In VS, select the project. For me this is PFTest3.
  2. In the right-click menu for the project, at the very bottom, click Properties. This opens the Property Pages dialog for the project.
  3. In the left pane, scroll down to C/C++ and then to Command Line under C/C++.
  4. In the Additional Options pane near the bottom of this dialog, type in /std:c++17 .
  5. Click OK. (I don't show this button in the screen shot below.)
You should then be able to build and run your code.
c++17option.png
 
  • Like
Likes jim mcnamara, yungman and jedishrfu
Mark44 said:
Here's what I did, and I'm running VS 2017.
  1. In VS, select the project. For me this is PFTest3.
  2. In the right-click menu for the project, at the very bottom, click Properties. This opens the Property Pages dialog for the project.
  3. In the left pane, scroll down to C/C++ and then to Command Line under C/C++.
  4. In the Additional Options pane near the bottom of this dialog, type in /std:c++17 .
  5. Click OK. (I don't show this button in the screen shot below.)
You should then be able to build and run your code.
View attachment 276866
Thanks so much Mark44. It works My program compiles.

I am really not into studying string_view. The Ivor book gave an example using string_view and I went nowhere on this. I only made up the little program to confirm it's VS.

What is that you are doing?

I was playing with this, you can actually click Project on the top bar, choose the last line PFTest3 properties and do the same thing.

Thanks so much,
 
This is the program that I am trying to understand and want to translate to using c-string so I can understand it better:
C++:
#include <iostream>
#include <cstring>
#include <string>
#include <string_view>
using namespace std;
class Trouble
{
private: string message;
public:
    Trouble(string_view str = " There is a problem") { message=str; }
    string_view what() const { return message; }
};
void trySomething(int i)
{
    if (i == 0) throw Trouble();
    else throw Trouble{ " Nobody knows the trouble I've seen..." };
}

int main()
{
    for (int i = 0; i < 2; i++)
    {
        try { trySomething(i); }
        catch (const Trouble& t) { cout << " Exception: " << t.what() << "\n\n"; }
    }
    return 0;
}

Still working on it, it's from Ivor book.
 
Please help me on this. I am translating the program in post#8 to use only c-string instead.

After I translate the program, it only print out the first letter of the string literal. eg, the first sentence is only "T" instead of "There is a problem". See output of program below.

I verified the way I pass the string literal to a function shown in line 20 to 23 and got the whole sentence "This is OutCstring test".

C++:
#include <iostream>
#include <cstring>
using namespace std;
const int csize = 51;
class Trouble
{ public:
    char message[csize];
    Trouble(const char *str)//Declare str pointer
        {
        strncpy_s(message, csize, str, csize);
        cout << " message: " << message << "\n\n";//Print out "There is a problem" first
        }
    char what() const  { return *message; }
};
void trySomething(int i)
{
    if (i == 0) throw Trouble("There is a problem");//Only pass the first letter "T"
    else throw Trouble( "Nobody knows the trouble I've seen..." );//Only pass letter "N"
}
void OutCstring(const char* C)//To show it passes the string literal
{
    cout << " The c-string passed to OutCstring is: " << C << "\n\n";
}

int main()
{
    OutCstring(" This is OutCstring test");//To proof I pass the whole sentence.

    for (int i = 0; i < 2; i++)
    {
        try { trySomething(i); }
        catch (const Trouble& t) { cout << " Exception: " << t.what() << "\n\n"; }//Only pass first letter.
    }
    return 0;
}
This is the output:
C++:
The c-string passed to OutCstring is: This is OutCstring test// test passing string literal to function

message: There is a problem //Print in line 11 to show message contains “There is a problem”

Exception: T //Only the first letter of the sentence “There is a problem”

message: Nobody knows the trouble I've seen... //Print in line 11 show it got copied correctly

Exception: N //Only the first letter of “Nobody knows the trouble I’ve seen……
I don't know what went wrong, please help
Thanks
 

Attachments

  • First letter.jpg
    First letter.jpg
    12.1 KB · Views: 169
Last edited:
  • #10
yungman said:
I don't know what went wrong, please help

Try look at the return type for your what() method.
 
  • Like
Likes jbunniii
  • #11
Filip Larsen said:
Try look at the return type for your what() method.
Thanks

I kind of thinking it's the return type, I should return the message, but if I remove the '*', it flag me an error. returning *message will give the content of the address of the first element of the c-string message which is the 'T'. But I don't know how to fix it. I try everything with that line already.

Thanks
 
  • #12
yungman said:
I kind of thinking it's the return type

It is so basic I wonder how you cannot spot it yourself. You have declared the what() method to return a char. Does this match any kind of string type? If no bell rings yet then try to look at one of the many examples involving C-strings you already have discussed here on PF.
 
  • #13
yungman said:
but if I remove the '*', it flag me an error

@yungman, you really, really, really need to go back and review the section on pointers. I know you've told us you know it. But you really need to learn it better. Randomly adding/removing *'s and &'s hoping it will hope shows that you don't have this down.

And getting back to the topic at hand, the reason it didn't work for you is because you need to tell VS you are using c++17. That's what @Mark44 does in his message.
 
  • #14
Vanadium 50 said:
the reason it didn't work for you is because you need to tell VS you are using c++17.

Since yungman indicate the code compiles and runs (but with, for him, unexpected results), I will maintain my earlier claim that a necessary condition to the what() to return a string is to change the return type to a string.
 
  • #15
Filip Larsen said:
Since yungman indicate the code compiles and runs

Did he? All he said was "I cannot even troubleshoot my program"
 
  • #16
Vanadium 50 said:
Did he? All he said was "I cannot even troubleshoot my program"

Ah, missed that you replied to the first post.
My reply is relevant for the code and question in post #8, which is the latest code sample (both now and when I replied).
 
  • #17
Vanadium 50 said:
@yungman, you really, really, really need to go back and review the section on pointers. I know you've told us you know it. But you really need to learn it better. Randomly adding/removing *'s and &'s hoping it will hope shows that you don't have this down.

And getting back to the topic at hand, the reason it didn't work for you is because you need to tell VS you are using c++17. That's what @Mark44 does in his message.
That is out of desperation because it doesn't make sense. I review my notes over, I NEVER managed to return a c-string from a function. I did asked here and I never got an answer, so I had to conclude I CANNOT return a c-string like that. If you know of a way, let me know.

Yes, I got that it's the VS from the very start already, that's why I asked in the first place. The error showed that it's obvious there's nothing wrong with the program, VS just won't compile without doing something. Never know VS needed to be told that it's C++17.
 
  • #18
I came up with a different way to return the message.
C++:
#include <iostream>
#include <cstring>
using namespace std;
const int csize = 51;
class Trouble
{ public:
    char message[csize];
    Trouble(const char *str)//Declare str pointer
        {     strncpy_s(message, csize, str, csize);     }
    ~Trouble() { cout << " In Trouble destructor.\n\n"; }
//    char what() const  { return *message; }
};
void trySomething(int i)
{
    if (i == 0) throw Trouble("There is a problem");
    else throw Trouble( "Nobody knows the trouble I've seen..." );
}
int main()
{
    for (int i = 0; i < 2; i++)
    {
        try { trySomething(i); }
        catch (const Trouble& t) { cout << " Exception: " << t.message << "\n\n"; }//just get the message directly!
    }
    return 0;
}

I just simply use t.message to get the message out. Easy peesy! I eliminated all the extra, but I added in the destructor to look at when it's out of scope.BTW, I did asked about function returning c-string here. I could not find anything in the book, I did not get any reply here. I search the web also. So I never have that in my notes. I concluded that it's NOT possible to return c-string from function. If you guys have a way, please let me know.

Also, seems like the Ivor books is the ONLY one that go deep into this exception. The C++ Primer book by Lippman arrived, it only has like 5 pages on exception, even less than Gaddis. Is exception that important? Why only Ivor put in so much effort in this? I finished Gaddis 20 pages in less than a week. All the time and debate are from the Ivor book. If exception is not that important, I am going to stop here. I already learn a lot more than in Gaddis book already. I want to move onto Template.

Thanks

Filip Larsen said:
Ah, missed that you replied to the first post.
My reply is relevant for the code and question in post #8, which is the latest code sample (both now and when I replied).

That's two completely different questions. My first question in OP is about VS, that was resolved thanks to Mark44. I just tagged on the second question in post 8. Vanadium50 mixed the two together.
 
  • #19
yungman said:
I did asked about function returning c-string here. I could not find anything in the book, I did not get any reply here. I search the web also.

Really?

First hit when searching for "c++ function returning c-string" (using duckduckgo):
https://stackoverflow.com/questions/1496313/returning-a-c-string-from-a-function

You could also try "what is a c-string" and see if that brings more light to your understanding of this.

The literature and the web is simply stock full of char * and const char *, and I have a hard time imagining how you could getting this far in your C++ exercises without never noticing what a C-string is. As you have been told by many by now, it is very difficult to assist you with appropriate hints when you "suddenly" are completely blank on some of the most basic concept.
 
  • #20
yungman said:
I NEVER managed to return a c-string from a function.

That is correct, and that is why I suggest you go over pointers again. A function cannot return a string. It can return a pointer to a string.
 
Last edited:
  • #21
Filip Larsen said:
Really?

First hit when searching for "c++ function returning c-string" (using duckduckgo):
https://stackoverflow.com/questions/1496313/returning-a-c-string-from-a-function

You could also try "what is a c-string" and see if that brings more light to your understanding of this.

The literature and the web is simply stock full of char * and const char *, and I have a hard time imagining how you could getting this far in your C++ exercises without never noticing what a C-string is. As you have been told by many by now, it is very difficult to assist you with appropriate hints when you "suddenly" are completely blank on some of the most basic concept.
I tried before, I can't find a way to make it work. This is the program I was working on, you can see the one in the middle doesn't work.
C++:
#include <iostream>
#include <cstring>
using namespace std;
const int csize = 21;
const char* retCstring1() 
    {
        return "Alan";
    }
const char* retCstring2()
    {    
        const char Cret[] = "Paul";
        return Cret;
}
void passCstring(char* C)
    {    
        strncpy_s(C, csize, "John", csize);
    }

int main()
{    int a;    char Cr[csize];
    strncpy_s(Cr, csize, retCstring1(), csize);
    cout << " Return from retCstring1: " << Cr << "\n\n";
    //strncpy_s(Cr, csize, retCstring2(), csize);
    cout << " Return from retCstring2: " << retCstring2() << "\n\n";//wont work.
    passCstring(Cr);
    cout << " passing from passCstring: Cr = " << Cr << "\n\n";    
    return 0;
}
The output is:
Garbage.jpg
 
  • #22
You should also review functions. A function that returns a string would need to have a string type. But C does not have a string type. (It does. however, have a pointer type)
 
  • #23
Vanadium 50 said:
You should also review functions. A function that returns a string would need to have a string type. But C does not have a string type. (It does. however, have a pointer type)
That's what I am talking about. I failed to see a way with this. I spent a lot of time on this. I know I can work around like in my final program bypass that. That's easy. My question is specifically on return c-string from a function.

I'll be really thankful if you can help making the middle one work. That's the essence of return a c-string. I really worked on it. I got so desperate I put '*' and const blindly all over already.

Hey, you can be logical, BUT if none work, the NEXT logical step is to go illogical!:)
 
  • #24
yungman said:
My question is specifically on return c-string from a function.

And you cannot do that. I've told you twice, Filip has told you once, and that's this thread. In your previous thread, Mark44 tells you twice, Jarvis323 tells you twice, and Halc and sysprog each tell you once. And if I searched more threads, I would find more examples.

Mark44 said:
It's disrespectful to us and wasteful of our time when we answer a question that you've asked, and you don't read the responses, and ask the same question again.

You really need to go back to the chapters on functions and pointers.
 
Last edited:
  • Like
Likes Filip Larsen
  • #25
To rehash and summarize:

1. A function cannot return a C-string in C. (Or C++)
2. A function can return a pointer to a C-string. However, one must take care to ensure this pointer points to the string, and not a memory location where the string used to be.
 
  • Like
Likes Jarvis323 and sysprog
  • #26
yungman said:
I tried before, I can't find a way to make it work. This is the program I was working on, you can see the one in the middle doesn't work.
C++:
const char* retCstring2()
    {
        const char Cret[] = "Paul";
        return Cret;
}
That's because retCstring2() is returning a dangling pointer. The array Cret[] is a local variable which goes out of scope as soon as the function returns. So, the pointer returned by retCstring2() points to memory that is no longer available.

The result is undefined behavior. If you're lucky the memory won't yet be overwritten when you try to use the pointer returned by retCstring2() , but in general this is not guaranteed. In the real world, Murphy's Law means that it will work when you test it, you'll ship it to customers, and it won't work for them.

As I've mentioned in a previous message in another thread, the only way to do what you're trying to do is to allocate an array of storage using new, copy the string into that array, and return a pointer to that array.

But then the burden falls on the caller of your function to delete the storage. This leads to all sorts of memory leaks when users fail to do so. The natural thing to do is to create a class that performs the new in the constructor and the delete in the destructor, hence cleans up after itself. But this is just a very poor duplication of what std::string already does, so why not use std::string?

The only other alternative is something like your Trouble implementation, which uses a fixed-size array and thereby avoids the new/delete issue. But this is a poor solution because it imposes a maximum string length (the size of the array must be a constant known at compile time), and every instance of this class will require the maximum fixed storage size, even if only using a tiny part of it!
C++:
class Trouble
{ public:
    char message[csize];
    Trouble(const char *str)//Declare str pointer
        {     strncpy_s(message, csize, str, csize);     }
    ~Trouble() { cout << " In Trouble destructor.\n\n"; }
//    char what() const  { return *message; }
};

No one should be messing around with C strings in 2021 unless they have a very good reason, such as (1) they're on a compiler team implementing the standard library, hence have to write std::string from scratch, or (2) they're on a primitive embedded platform that doesn't provide dynamically allocated memory and therefore cannot provide a std::string implementation.
 
Last edited:
  • Like
Likes Mark44 and pbuk
  • #27
This is absolutely golden advice:

jbunniii said:
No one should be messing around with C strings in 2021 unless they have a very good reason, such as (1) they're on a compiler team implementing the standard library, hence have to write std::string from scratch, or (2) they're on a primitive embedded platform that doesn't provide dynamically allocated memory and therefore cannot provide a std::string implementation.

In the real world, we write exceptions in C++ to throw objects with integer (enum) error codes. If a human language message needs to be displayed/logged this can be dealt with in the error handling block of the calling code.
 
  • #28
jbunniii said:
No one should be messing around with C strings in 2021

I have been saying that from the start too! But someone here keep insisting on continuously experiencing and share how easy is it to shoot yourself in the foot (or other appropriate body part) with these strings :wink:.

(For the record, I give said someone plus points for stamina, but minus point for not learning from earlier mistakes - and myself minus points for keep falling into the trap of answering :rolleyes:).
 
  • #29
Filip Larsen said:
I have been saying that from the start too! But someone here keep insisting on continuously experiencing and share how easy is it to shoot yourself in the foot (or other appropriate body part) with these strings :wink:.

(For the record, I give said someone plus points for stamina, but minus point for not learning from earlier mistakes - and myself minus points for keep falling into the trap of answering :rolleyes:).
The reason is Gaddis book mainly use c-string for everything. I am still using the Gaddis and do the exercise. Gaddis book still have the best program examples, even have CD that contain all the programs. I cannot just drop it. I have no choice at this point! After learning exception,Templates and the few chapters on data structure, then if I have time, I can go back in the future, but not now.

Yes, I notice Ivor book and the newly acquired C++ Primer by Lippman both exclusively using std::string. Lippman book is better than Ivor, BUT it really doesn't have complete program that I can work on, just snipped of codes. Ivor is hard to understand period, we went through a big debate on that already. Lippman book is better for reading. So I am still confined to reading Lippman and working on Gaddis...Meaning a lot of c-string.

Also, c-string is faster in run time than std::string. I have to learn string_view of C++17 to speed it up. That's one more to learn for me where I am trying to finish Gaddis book.

Yes, I notice std::string is much easier to use.
 
  • #30
yungman said:
I notice Ivor book and the newly acquired C++ Primer by Lippman both exclusively using std::string. Lippman book is better than Ivor, BUT it really doesn't have complete program that I can work on, just snipped of code.

I am not familiar with Lippman's book, but hopefully you should quickly be able to work those snippets into your own context pretty quickly (just like you seem to do with the code you have from Gaddis).

yungman said:
c-string is faster in run time than std::string.

Even if that claim was true (which I strongly doubt; modern std::string or similar implementations are highly optimized for performance while still maintaining easy and safe use), I can't help wondering what kind of program you plan to make where you think any performance difference between the two will be an issue?

I ask because run-time performance obviously does not matter one bit when you are just learning the basics, so if you are worried about speed you must be thinking of some usage situation and not about learning, right?
 
  • Like
Likes jbunniii and pbuk
  • #31
Filip Larsen said:
Even if that claim was true (which I strongly doubt; modern std::string or similar implementations are highly optimized for performance while still maintaining easy and safe use), I can't help wondering what kind of program you plan to make where you think any performance difference between the two will be an issue?

I ask because run-time performance obviously does not matter one bit when you are just learning the basics, so if you are worried about speed you must be thinking of some usage situation and not about learning, right?
I read it on line to justify going into string_view.

I hope I don't offend you below:

I designed a lot of hardware, there are situations time is critical. That goes back to a lot of times I mentioned and people disagree here. I notice EVERY single piece of hardware/appliance, be it cars, tv, computers, printers...everything that using firmware and/or software are getting slower and slower while the speed of hardware and processors are getting faster. I blame it on software people taking for granted that hardware is fast, they they can be more fancy and don't worry about the speed. I just do NOT want to be one of them. I respect hardware people that bent over backwards, breaking their backs to squeeze out the last bit of speed just to be wasted and take for granted by others. Do you know how hard it is to squeeze the speed, generation of hardware engineer, pcb designers are forced out because they don't have the knowledge of microwave to do design? The bus system on the pcb is NOT just a trace, you have to worry about reflection, crosstalk and all that.

I know how to design these, I spent years studying calculus, ODE, PDE in order to study electromagnetic to design microwave hardware. I few sorry towards those that don't. Out of respect, I will NOT wasting the speed away no matter what. There is a lot of blood sweat and tears to this.
 
  • #32
yungman said:
I designed a lot of hardware, there are situations time is critical.

Granted, on (small or special) embedded devices you may have limited resource and the programming environment may also be fairly limited (e.g. no heap and similar), but then I would think you would probably also be coding more in C than "full" C++ (and C-strings obviously makes sense to learn about if you want to code in C).

I would still venture the guess that you would be hard pressed to find an embedded device with accompanying SDK supporting full C++ but only in such a way that resource managed strings (like std::string or its replacement on that particular platform) are significantly slower than "unmanaged" raw string pointers. My point here is that if you have C++ you also have the means to encapsulate the complexities for handling raw string pointer in a class (whether they are null terminated or length based) without being forced to loose performance.

Also, if "string" processing performance is critical on an embedded CPU device, perhaps some of it should be handled by a DSP or a FPGA instead. For instance, at my work we do mostly C++ with a dash of OpenCL code that is deployed to data processing GPU's and special FPGA's. Managing buffers in that context is similar to C-string handling, but even so we have handy C++ classes to wrap all the lower-level stuff.
 
Last edited:
  • Like
Likes jbunniii
  • #33
Filip Larsen said:
Even if that claim was true (which I strongly doubt; modern std::string or similar implementations are highly optimized for performance while still maintaining easy and safe use), I can't help wondering what kind of program you plan to make where you think any performance difference between the two will be an issue?
Agree strongly with this. Any modern compiler will have a highly optimized implementation of std::string and other standard library features. (Additionally, they have even-more-optimized specializations for small strings which require almost no overhead beyond the storage for the characters themselves.) It's a premature pessimization to assume otherwise, especially if it means trading the safety and convenience of std::string for the terribly error-prone and limited C string. The latter is hardly suitable for high performance without extra bookkeeping anyway. Even simple operations like determining the length of a C string (strlen) require iterating through the entire string to look for the terminating '\0'.

Moreover, @yungman, I strongly suspect that in most/all of the use cases for which you are considering std::string_view, you could achieve the equivalent by simply passing a std::string by reference instead of by copy. Can you show an example where you think this is not the case?
 
  • Like
Likes Filip Larsen
  • #34
yungman said:
I notice std::string is much easier to use.

Indeed, and that ease of use goes directly into better code quality, more flexible code and higher coding speed (and more fun doing all that) :smile:
 
  • #35
yungman said:
I read it on line to justify going into string_view.

I hope I don't offend you below:

I designed a lot of hardware, there are situations time is critical. That goes back to a lot of times I mentioned and people disagree here. I notice EVERY single piece of hardware/appliance, be it cars, tv, computers, printers...everything that using firmware and/or software are getting slower and slower while the speed of hardware and processors are getting faster. I blame it on software people taking for granted that hardware is fast, they they can be more fancy and don't worry about the speed. I just do NOT want to be one of them. I respect hardware people that bent over backwards, breaking their backs to squeeze out the last bit of speed just to be wasted and take for granted by others. Do you know how hard it is to squeeze the speed, generation of hardware engineer, pcb designers are forced out because they don't have the knowledge of microwave to do design? The bus system on the pcb is NOT just a trace, you have to worry about reflection, crosstalk and all that.

I know how to design these, I spent years studying calculus, ODE, PDE in order to study electromagnetic to design microwave hardware. I few sorry towards those that don't. Out of respect, I will NOT wasting the speed away no matter what. There is a lot of blood sweat and tears to this.
The most important thing is to know what you're doing first. If you did have a use case where c-strings performed better than std::string, would it matter anyway if your code is wrong, crashes randomly, hangs, gives wrong results etc.

I suggest that you should first figure out what a c-string is and what an std::string is, how to use them, and then figure out in which cases one might be faster than the other, and by how much, by testing the performance.

It's always important to know what you are doing, both when it comes to programming logic, syntax, etc., and optimization.
 
  • #36
I really don't know enough about comparing strings with c-string which one is faster. Like I said, I don't think I have much of a choice at this point like I described in post 29. I know I should learn everything, but I just can't, I have to choose my path of using Gaddis for exercise. I actually used all std::strings before as it is much easier to use, I did learn the member functions and all that. But I have no choice but to change to c-string because of the book. You guys know C++, it's easy to say one way or the other.

Remember I am self study, even with all your help, it's still down to me reading the books. I already bought 5 or 6 books already, Only Gaddis is the simplest one and provide all the sample program to play with. I tried other books, I cannot deal with Ivor's book that at least have some programs. Lipman's book don't have exercise. What choice do I have at this point? I just have to bull through all the chapters and complete the Gaddis book. Then I can venture out to different things. I don't want to jump around. It's not as if I want to stuck with c-strings. Std::string is much easier to deal with for sure.
 
  • #37
You might want to take a pause and learn about memory. The issues you've had with c-strings have been mostly been due to a lack knowledge about this. With c-strings, you are working with memory addresses to stored values. Using higher level features you can get away with not understanding these things, but not using things like c-strings. You need to know where your c-string is (stack, heap, static) and when/how it gets destroyed. If you know these things, then you have no reason to ask us how to return a c-string.

https://www.google.com/amp/s/crafto...emory-in-c-the-stack-the-heap-and-static/amp/
 
  • Like
Likes yungman
  • #38
FYI, I actually spend time on std::string the last two days. I was playing with and even added my own lines to this program from Ivor book to try to understand the string_view and the new way of writing constructor like MoreTrouble(string_view str = " There is more trouble...") : Trouble{str}{}. I have to translate this to line 19 and 20 so it's easier for me to read. I don't even know what you call this to try to look online how to write it. I literally have to guess, run and compare the result to confirm!

C++:
//Matching catch handler with exception
#include<iostream>
#include<string>
#include<string_view>
#include<cstring>
using namespace std;
class Trouble
{
private:
public:
    string message;
    Trouble(string_view str = " There is a problem")//12, 12,
        { message = str; }//30, 31, 19,
    virtual ~Trouble() = default;//Base classes must have virtual des.
    virtual string_view what() const { return message; }//
};
class MoreTrouble : public Trouble
{
public: MoreTrouble(string_view str = " Theres more trouble")//19, 19,
    : Trouble(str){}//11, 11, 25,
      ~MoreTrouble() { cout << " Destructor MoreTrouble.\n\n"; }
};
class BigTrouble : public MoreTrouble
{
public: BigTrouble(string_view str = " Really big trouble") //25,
    : MoreTrouble(str) {};//18, 32,
      ~BigTrouble() { cout << " Destructor BigTrouble.\n\n"; }
};
int main()
{    Trouble trouble;//11,
    MoreTrouble moreTrouble; //18,
    BigTrouble bigTrouble;//24,
    cout << trouble.message << "\n\n";
    cout <<moreTrouble.message << "\n\n";
    cout << bigTrouble.message << "\n\n";
    trouble.message = " change to New trouble";
    cout << trouble.message << "\n\n";
    cout << moreTrouble.message << "\n\n";
    cout << bigTrouble.message << "\n\n";
    moreTrouble.message = " change to New moreTrouble";
    cout << trouble.message << "\n\n";
    cout << moreTrouble.message << "\n\n";
    cout << bigTrouble.message << "\n\n";
    bigTrouble.message = " change to New bigTrouble";
    cout << trouble.message << "\n\n";
    cout << moreTrouble.message << "\n\n";
    cout << bigTrouble.message << "\n\n";
    for (int i = 0; i < 7; ++i)
    {    try
        {
            if (i == 3) throw trouble;//
            else if (i == 5) throw moreTrouble;//
            else if (i == 6) throw bigTrouble;        }
        catch (const BigTrouble& t) { cout << " BigTrouble obj caught: " <<
            t.what() << "\n\n"; }//
        catch (const MoreTrouble& t) { cout << " MoreTrouble obj caught: " <<//
            t.what() << "\n\n"; }//
        catch (const Trouble& t) { cout << " Trouble obj caught: " <<//
            t.what() << "\n\n"; }//
        cout << " End of for loop(after catch blocks), i = " << i << "\n\n";
    }
}

I have been working on this many hours a day, it's not as if I don't try. It's just a lot of things to learn. At this point, I feel my head is spinning.
 
  • #39
Jarvis323 said:
You might want to take a pause and learn about memory. The issues you've had with c-strings have been mostly been due to a lack knowledge about this. With c-strings, you are working with memory addresses to stored values. Using higher level features you can get away with not understanding these things, but not using things like c-strings. You need to know where your c-string is (stack, heap, static) and when/how it gets destroyed. If you know these things, then you have no reason to ask us how to return a c-string.

https://www.google.com/amp/s/crafto...emory-in-c-the-stack-the-heap-and-static/amp/
Actually I deleted my last response to you. Yes, I spent over a day studying c-string. The thing that I understand now is c-string does not have a type like int, char etc. So I cannot return a c-string in a function. Yes, there's a lot of limitation using c-string more codes need to copy and all. std::string is just a lot easier to use. In fact I used std::string until like 3 months ago and had to switch to c-string because of Gaddis that time.

Thanks
 
  • #40
yungman said:
Actually I deleted my last response to you. Yes, I spent over a day studying c-string. The thing that I understand now is c-string does not have a type like int, char etc. So I cannot return a c-string in a function. Yes, there's a lot of limitation using c-string more codes need to copy and all. std::string is just a lot easier to use. In fact I used std::string until like 3 months ago and had to switch to c-string because of Gaddis that time.

Thanks
Also, std::string is really, basically, just a c-string coupled with a variable that tracks its size, and some operators to do things like deep copy.

If you really wanted to return a c-string that is on the stack, one way to pull it off, would be to make a struct that manages it and can make deep copies in the operator= and copy constructor, etc. Something like this

C:
struct cstringWrapper {
    size_t size;
    char * cstring;
    cstringWrapper & operator=()...
    cstringWrapper( const cstringWrapper & other) ...
};

Then, you can return it by value, and it will automatically deep copy the stored data for you. But this is basically what an std::string is. It's just a c-string that is managed by a class.

The other thing you can do is use smart pointers, like std::unique_ptr/std::shared_ptr. These are pointers to stuff on the heap, that are automatically freed, so you don't have to worry about deleting it yourself. They are kind of like C++'s (sort of) answer to have something like reference counting and automatic memory management.

https://web.stanford.edu/class/archive/cs/cs106l/cs106l.1184/lectures/lecture15/15_RAII.pdf

std::string_view is new, and I've not even heard of it until now. But std::string is already really fast. Unless you are doing a whole lot of certain types of string operations (like millions or billions of them), then you are probably not going to save any noticeable amount of time. And using raw c-strings or string_view is not a solution to returning a local string (that is on the stack).

People will tell you, they can't stress it enough, premature optimization is bad. It's fine if you want to maximize performance, but starting blindly with c-string optimizations is not the way to go. That is most often going to be one of the last things worth trying, if at all. It usually won't make any noticeable difference. Donald Knuth made a big deal about it, saying,

“The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.”

https://stackify.com/premature-optimization-evil/

And Knuth is the one that wrote some of the most famous books on efficient algorithms. He invented analysis of algorithms, and our concept of time complexity. He wrote all of his books using assembly language to implement the examples. He is not the one you can complain about when you find your software is slow.

If you learn about data structures and algorithms and time complexity, one thing you'll realize is that the algorithm is the most important thing. You can spend days trying to optimize the strings, maybe using c-strings, or std::strings. Maybe sometimes you end up finding std::string is sort of faster, maybe sometimes string_view or c-string saves some time, probably maybe a few microseconds. But a change to the algorithm can make a huge difference. You can write your program in a high performance language like C++, using the GPU, and multi-threading even, and you can spend years micro-optimizing. But someone might just use a more clever algorithm, or wiser choice of data structures, even implemented in a slower language like python, and beat your algorithm like a rabbit vs a turtle in a race. I've seen this happen so many times.
 
Last edited:
  • Like
Likes pbuk and Filip Larsen
  • #41
Jarvis323 said:
But std::string is already really fast. Unless you are doing a whole lot of certain types of string operations (like millions or billions of them), then you are probably not going to save any noticeable amount of time.

This.

And that Knuth fellow seems pretty clever.

The only other things I would say would be:
  • I would be surprised if the time difference betyween C and STL strings was any more than the time difference from using "<<" as opposed to printf.
  • "This works better for embedded processors" is not a good argument if you are not writing for embedded processors.
  • Speed is no substitute for correctness. Getting a wrong answer faster is not really a benefit.
 
  • Like
Likes jbunniii and Filip Larsen

Similar threads

Replies
19
Views
1K
Replies
1
Views
1K
Replies
22
Views
3K
Replies
8
Views
2K
Replies
5
Views
3K
Replies
1
Views
1K
Back
Top