16 Jun, 2007, Ugha wrote in the 1st comment:
Votes: 0
Alright, you guys made a good point.

What about another topic… C++ strings vs C strings.

What the heck is wrong with C strings? I understand C++ strings have a lot of features like buffer overflow protection and such, but whats
the point when you have to end up converting them back to C strings to use almost any of the existing functions?

PS: I have a lot of other MUD related topics I think would be interesting in a debate, do you guys think a regular series of debates would be
fun or would it end up being a flame war?
16 Jun, 2007, Justice wrote in the 2nd comment:
Votes: 0
Ugha said:
What about another topic… C++ strings vs C strings.

What the heck is wrong with C strings? I understand C++ strings have a lot of features like buffer overflow protection and such, but whats
the point when you have to end up converting them back to C strings to use almost any of the existing functions?


There's absolutely nothing wrong with C strings. Generally speaking, I prefer C++ strings because they are safer to use. What is better really depends on what you're doing. I once had to write a data processing program that worked on large database dumps. That is pipe and newline delimited files that were several gb in size. For this application, performance was much more important than safety, since even a single unnecessary statement added several minutes to the execution time. However it's the only thing I've run into where C++ strings weren't more than fast enough.

When working with older C code, I tend to leave C strings alone, but use C++ strings for buffers and areas where the additional safety is useful.

Ugha said:
PS: I have a lot of other MUD related topics I think would be interesting in a debate, do you guys think a regular series of debates would be
fun or would it end up being a flame war?


I don't think the majority of people here would have any problems with it. There are always those who like to flame, we shouldn't let them spoil our fun.
16 Jun, 2007, Zeno wrote in the 3rd comment:
Votes: 0
I see almost no reason to use C strings over C++ strings. C++ strings has a ton of useful built in methods, saving to a lot of time.
16 Jun, 2007, Guest wrote in the 4th comment:
Votes: 0
Sorry for the confusion, but I figured it best to split the topic now rather than wait a few days and have it less defined :P

For me at least, I find C++ strings relatively easy to work with and understand. Things like searching and replacing parts of a string, which I struggle with badly in C to this day, are a breeze in C++. If I had the time I'd probably have converted most of my codebase to use std::string by now.

The only time C strings become easier to deal with is using formatted output, like sprintf. C++ has some rather ugly and overcomplicated ways to accomplish the same thing.
16 Jun, 2007, KaVir wrote in the 5th comment:
Votes: 0
Ugha said:
What the heck is wrong with C strings?


C doesn't directly support strings as a type, only arrays of characters terminated by a NUL character, which can be stored in a number of different areas of memory (the data segment, the heap or the stack). It is very easy to accidently cause crashes or memory leaks, particularly if you don't take into account the NUL character in the string length, or you mix up where a variable is stored - I think I've probably seen more mud-related bugs caused by a misunderstanding of C strings than anything else.

If I were writing my mud in C, I would create my own string module to reduce the chances of making a mistake when developing the mud (C strings are one of my strong points, but I'm not infallable, and bugs with string handling can sometimes prove extremely hard to track down). However because I'm using C++, I get that functionality for free, giving me more time to work on other things.
16 Jun, 2007, Ugha wrote in the 6th comment:
Votes: 0
So we take an extremely well established policy of using a character array, and throw it out the window?
What about the tons of functions out there that require a null terminated string?
Not to mention overhead… don't C++ strings take far more memory and processor time (as Justice mentioned)
to use?
16 Jun, 2007, Dorian wrote in the 7th comment:
Votes: 0
Samson said:
The only time C strings become easier to deal with is using formatted output, like sprintf. C++ has some rather ugly and overcomplicated ways to accomplish the same thing.


Try Boost Format library. Useful, 'printf'-like, and type safe!

Ugha said:
So we take an extremely well established policy of using a character array, and throw it out the window?


I would hardly call it a "well established policy". People have been trying to get away from it for years. For example, Windows had some construct called a BSTR (I _think_) which kept a non-null terminated string but kept its length as well.

Ugha said:
What about the tons of functions out there that require a null terminated string?


Use a null-terminated string?

Ugha said:
Not to mention overhead… don't C++ strings take far more memory and processor time (as Justice mentioned)
to use?


No. Some platforms are slower than others, but its negligible.
17 Jun, 2007, Guest wrote in the 8th comment:
Votes: 0
Dorian said:
Samson said:
The only time C strings become easier to deal with is using formatted output, like sprintf. C++ has some rather ugly and overcomplicated ways to accomplish the same thing.


Try Boost Format library. Useful, 'printf'-like, and type safe!


That formatting lib looks nice and all but in the context of what we're all covering here, it may not be available for everyone. Boost isn't as widely adopted as one might think.
17 Jun, 2007, Justice wrote in the 9th comment:
Votes: 0
Ugha said:
So we take an extremely well established policy of using a character array, and throw it out the window?
What about the tons of functions out there that require a null terminated string?
Not to mention overhead… don't C++ strings take far more memory and processor time (as Justice mentioned)
to use?


C++ strings are more than fast enough for almost every purpose. The example I mentioned is an extreme case where it was necessary to process several gb in minutes. When writing new code, I prefer to use C++ strings. As KaVir mentioned, the vast majority of fatal bugs in muds relate to poor usage of C strings. I haven't done a formal study of the resource differences between the two, but in most cases the time saving from debugging and writing code is worth it.
17 Jun, 2007, Tyche wrote in the 10th comment:
Votes: 0
Ugha said:
What about the tons of functions out there that require a null terminated string?


NUL terminated strings, not NULL terminated. ;-)

Quote
Not to mention overhead… don't C++ strings take far more memory and processor time (as Justice mentioned)
to use?


STL strings have an additional 8 byte overhead. They are in some cases faster since some implementations store the length. There are immutable string libraries which share strings and would actually use less memory.

There's string libraries for C. The C Safe String Library was written by two LP mudders.
17 Jun, 2007, Davion wrote in the 11th comment:
Votes: 0
So you use STL string for anything except when extreme speed is necessary, but does this hold true for all STL containers? This is a bit broader, and probably more C Arrays/Lists Vs. C++ Containers.

For those that don't know, the containers I'm talking about are ones like vector, map, and list.
17 Jun, 2007, Dorian wrote in the 12th comment:
Votes: 0
Tyche said:
STL strings have an additional 8 byte overhead.


Hm?

Quote
dan@ubuntu:~$ cat > string.cpp
#include <iostream>
#include <string>

int main()
{
std::cout << sizeof(std::string) << " " << sizeof(char *) << std::endl;
}
dan@ubuntu:~$ g++ -o string string.cpp
dan@ubuntu:~$ ./string
4 4
dan@ubuntu:~$


Not all implementations have such an overhead.
17 Jun, 2007, Justice wrote in the 13th comment:
Votes: 0
Davion said:
So you use STL string for anything except when extreme speed is necessary, but does this hold true for all STL containers? This is a bit broader, and probably more C Arrays/Lists Vs. C++ Containers.

For those that don't know, the containers I'm talking about are ones like vector, map, and list.


I haven't had any issues with the standard containers. My GZA code uses std::map to store rooms in a sparse coordinate plane using the coordinate as a key. It also uses std::multimap to store items types on items. I use std::list for many things and have never really had issues with it. The BFS implementation I have uses std::list for it's primary processing queue. I also use a std::map for the "closed" list. That is, to prevent it from visiting rooms that have already been processed. SMAUG uses a room flag to handle this. Anyway… this handles searches with a distance of 30-50 with acceptable performance. I don't remember exactly how fast it was, but it's fast enough to handle several thousand explosions on my GZA code without impacting a 50ms pulse. Each explosion used a LOS search with a range of 5, and a BFS search with a range of 10.

[edit]The LOS was to apply damage to any characters/objects in direct line of sight from the explosion, the BFS was to create an "audible" effect.[/edit]
17 Jun, 2007, Guest wrote in the 14th comment:
Votes: 0
I've not noticed any significant changes in memory usage or performance using STL code but there was a major rise in the size of the binary and object files after the mud is compiled. Personally I can live with that, but it could be something to consider on a space-limited account.
18 Jun, 2007, Tyche wrote in the 15th comment:
Votes: 0
Dorian said:
Tyche said:
STL strings have an additional 8 byte overhead.


Hm?


Hm..sizeof()? ;-)
Okay if you are using GNU C++ STL then the overhead is 16 bytes for each string (assuming single byte characters, 4 byte integers and pointers), so 8 bytes is overly generous. Please read the source code (basic_string.h). A String contains a pointer to it's representation. The representation contains a 12 byte area immediately followed by the character array. The pointer to the representation is set to the start of the character array as a convenience to those using the Gnu debugger.

To demonstrate:
$ cat str.cpp 
#include <iostream>
#include <string>
using namespace std;
int main(){
string s("hello world");
char* c;
int *size, *capacity, *shared;

c = (char*)s.c_str();
size = (int*)(c-12);
capacity = (int*)(c-8);
shared = (int*)(c-4);

cout << "size: " << *size << endl;
cout << "capacity: " << *capacity << endl;
cout << "shared: " << *shared << endl;
return 0;
}

$ g++ str.cpp ; ./a
size: 11
capacity: 11
shared: 0


So the string "Hello World" on my platform using GNU C++ STL…

Pointer in String - 4 bytes
Size - 4 bytes
Capacity - 4 bytes
Refcount - 4 bytes
Character array - 11 bytes
NUL character - 1 byte
———————
28 bytes

In C the string would take 12 bytes to store
18 Jun, 2007, Dorian wrote in the 16th comment:
Votes: 0
Tyche said:
(snip)
In C the string would take 12 bytes to store


Ah, I see what you're saying now. Wasn't exactly sure to what you were referring.
20 Jun, 2007, Ugha wrote in the 17th comment:
Votes: 0
Did you forget padding for byte alignment? Or is that in C structures and such only?
20 Jun, 2007, Tyche wrote in the 18th comment:
Votes: 0
The default compiler alignment option in both GNU C and C++ is on word boundaries. So the "hello world" char array just happens to cause exactly 12 bytes to be allocated. The char array "hello world1" would cause 16 bytes to be allocated instead of 13 under the default alignment option.
20 Jun, 2007, Caius wrote in the 19th comment:
Votes: 0
Samson said:
I've not noticed any significant changes in memory usage or performance using STL code but there was a major rise in the size of the binary and object files after the mud is compiled. Personally I can live with that, but it could be something to consider on a space-limited account.

The increase in binary size seems to relate mostly to debugging symbols. My own binary has grown from about 11MB to 19MB after I started using STL containers. However, when I strip the binary, the difference is only a couple of houndred kilobytes.
0.0/19