Timeline for how to nicely use constant std::string in c++
Current License: CC BY-SA 3.0
14 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Apr 9, 2021 at 17:28 | comment | added | user2445507 |
@EdwardStrange Wrong. std::string uses heap. So a std::string constant will also use heap, while const char* just uses static memory. std::string will also do some work during construction, which is also non-zero. This is noticeable if you have tight performance requirements and/or large strings. Finally, there is the semantic difference. std::string is generally mutable while const char* is unambiguously a constant.
|
|
Mar 12, 2015 at 18:29 | comment | added | Ben Voigt |
I have to disagree with nearly all of @CrazyEddie's comment. std::string does add overhead, namely dynamic allocation, and string copy, and a field for storing the size at runtime. The size of a std::string is calculated at runtime, the number of elements in a const char[] is a compile-time constant. The only advantage of std::string is the interface. Someone should provide a library of string manipulation functions that take character arrays as input and return RAII object (std::string or similar) of the needed size as output, thus both efficient and immune to buffer overflow.
|
|
May 23, 2012 at 16:13 | comment | added | David Thornley | It is very useful to name your strings and not hard-code them into the code where used, if you ever internationalize your code. Digging the strings out of the code is a real pain, and you don't want to miss one. | |
May 21, 2012 at 0:19 | comment | added | Pubby | @CrazyEddie Could you explain what you mean with "has a well defined and determined end that is a pre-calculated aspect of the instance's state"? I am very interested in hearing your full explanation, perhaps write an answer to this question? | |
May 20, 2012 at 16:51 | comment | added | Edward Strange | -1 for the last paragraph. The std::string class does NOT add a bunch of extra overhead when used in this manner, has a well defined and determined end that is a pre-calculated aspect of the instance's state (unlike C strings), retains consistency by not using one API for some strings and another for others,...etc...I could go on and on. This is really bad advice in an otherwise decent answer. | |
May 20, 2012 at 11:43 | comment | added | Giorgio | @Pubby: "Not really a problem with error messages though.": In my case it was some constants that are defined by translation unit a and used by translation unit b during initialization. So I really want to import the constants defined in a.cpp into b.cpp. Maybe the only bullet proof solution is indeed to use macros. | |
May 20, 2012 at 11:43 | comment | added | Pubby |
@Giorgio AFAIK You still can't guarantee the initialization order of const char[] across translation units, but it uses constant initialization which occurs before dynamic initialization. In practice I think it will always work as they're stored in the binary.
|
|
May 20, 2012 at 11:40 | comment | added | Giorgio | Yes, I meant translation units (.cpp files that are translated to object files). The situation was a.cpp containing the constant strings and accessor functions, and b.cpp calling those functions. Since b.obj is loaded before a.obj, all strings were still "". I solved the problem by using macros, but I think the const char[] solution is the best one. +1 for the tip. | |
May 20, 2012 at 11:37 | comment | added | Pubby |
@Giorgio Yeah, that's correct, although it's translation units and not modules. They're created before main begins (at least from observation), but in an unspecified order between translation units. Not really a problem with error messages though.
|
|
May 20, 2012 at 11:37 | comment | added | Giorgio | @Pubby: I recently had the problem that I accessed some const std::string variables from a different .cpp file and they were "" (probably not initialized yet). So I would say that using const char[] is definitely better because it avoids this kind of problems too. | |
May 20, 2012 at 11:33 | comment | added | Pubby |
@stefan const char is more efficient. std::string has quite a bit of overhead and requires dynamic initialization. It's not a huge issue, but I still recommend using const char[] if possible.
|
|
May 20, 2012 at 11:31 | comment | added | Giorgio | Maybe because const char is initialized at compile time while std::string is initialized when the containing module is loaded. Then you might have an error if modules are not loaded in the order you expect. At least this is what I suspect can explain some bugs I had lately. If someone can comment on this theory I would be glad to learn more. | |
May 20, 2012 at 11:25 | comment | added | stefan | Yes, I do realize it's not really avoiding "hardcoding", but I don't see a cleaner way to still get compiler warnings if a string is missing. Some messages are present in multiple cpp-files, so storing them elswhere seems to be a good idea. Why are you suggesting the use of const char[]? Why should this be better? | |
May 20, 2012 at 11:19 | history | answered | Pubby | CC BY-SA 3.0 |