
Reece Dunn wrote:
Rob Stewart wrote:
From: John Nagle > Reece Dunn wrote:
Rob Stewart wrote:
From: John Nagle The question is, which is better: char_string<4> or boost::array<char,4>? I suggest that the latter is better. In C code, and similar C++ code, arrays of char are used as buffers of fixed length and as memory for strings. Code will be clearer if one uses boost::array<char,N> for the former and char_string<N> for the latter. Once you make that distinction of purpose, null termination can be integral to char_string without complication or unwanted overhead.
That makes sense.
Agreed. If you're doing something that requires an array of characters of a specific size, it's often part of some structure defined by some external standard, like a Macintosh file signature or an ISO CD header. There, you need something that contains exactly the characters specified, and nothing else. "boost::array<char,N>" is thus the right tool for that job.
What about the base class issue? There's a need to be able to write something like "char_string_base& s" when you want to pass around fixed-capacity strings of more than one capacity.
If that is a necessary feature, then the length can be stored in the base class. However, such a base class means that the dtor must be virtual. Is vtable overhead acceptable in such a class? Perhaps two types are needed.
My design does not use a virtual base class, so that isn't an issue. John Nagle's version does, so that is where the problem arises. I have several issues with the use of a virtual base class:
[1] If you want to operate on a variable length character string specifically, why not templatize the function: template< int n > void myfn( boost::char_string< n > & s ){ ... }
That leads to templatizing every function that has a char_string argument, with the associated headaches and overhead. It's not easy to retrofit that to existing code without a major rewrite. With a base class approach, you can just replace "char *" with "char_string_base&", then fix any compile errors, and your program becomes buffer overflow safe. That's easy to do.
[2] How do you deal with wide-character strings? My update generalizes to support char and wchar_t based buffers, but with a virtual base class, you are limited to char buffers.
I'm assuming that wchar_string will be much like char_string, but may be a separate file. The functions it has to call (strncat vs. wstrncat) have different names, so you can't just crank out both forms with a template anyway.
[3] One of the reasons for having a virtual class is to supply custom string operations, e.g. using Windows-specific string functions instead of the standard library ones. This can also be solved with a policy template like that found in basic_string. My current version uses this approach, improving interoperability with basic_strings.
Did you ever put this in the Boost sandbox? John Nagle