Boost logo

Boost :

From: Rob Stewart (stewart_at_[hidden])
Date: 2004-05-27 15:21:33


From: "Reece Dunn" <msclrhd_at_[hidden]>
> Rob Stewart wrote:
> >From: "Reece Dunn" <msclrhd_at_[hidden]>
> > > John Nagle wrote:
> > > > The big question is whether the size specified in the
> > > >declaration (as in "char_string<80>") includes the
> > > >trailing null.
> > > >
> > > I have modified the sandbox implementation to make it easy to switch
> >between
> > > the two models; it is currently using the 2nd model (adding space for
> >the
> > > null). One possibility is putting the choice of models as a template
> > > parameter (e.g. bool need_null -- see comments in the sandbox code for
> >an
> > > implementation), that way the decision is up to the programmer and not
> >the
> > > library implementor.
> >
> >This is overkill.
>
> I think you misunderstand what I am trying to say. See my comments below.

Actually, I think you misunderstood my points.

> >Given that assumption, look to the syntax you're replacing:
> >
> > char s[] = "1234567890";
> > assert(10 == strlen(s));
> > size_t const LENGTH = 3;
> > char t[LENGTH + 1];
> > strncpy(t, "ABCEFGHIJKLMNOP", LENGTH);
> > assert(LENGTH == strlen(t));
> >
> >Now do the same with the new class:
>
> The equivalent would be:
>
> fixed_string< 15 > s( "1234567890" ); // [1]
> assert( 10 == strlen( s )); // C-style
> assert( 10 == s.size()); // C++-style
>
> const size_t LENGTH = 3;
> fixed_string< LENGTH > t; // [2]
> t = "ABCEFGHIJKLMNOP";
> assert( LENGTH == strlen( t )); // C-style
> assert( LENGTH == t.length()); // alternate C++-style
>
> [1] You need to specify the size of the buffer. You cannot declare an object
> of type fixed_string_base (as it is abstract), you can only have references
> and pointers to it so you can operate on variable-capacity strings.

Ah, but you missed that I was declaring a fixed_string_base,
where string capacity is not known. I was relying on
make_fixed_string() to deduce the array length and create an
appropriate fixed_string for it.

> [2] This is the point that we are discussing. Should this line be:
>
> fixed_string< LENGTH > t;
>
> as will work with the current sandbox implementation (my suggestion #2), or
> should it be:
>
> fixed_string< LENGTH + 1 > t;

And that's exactly my point. It should be the former as shown by
my equivalencies.

> Different programmers favour the different semantics, so I ask: why not
> parameterise it, providing a default behaviour.

I'm not so sure they do and I'm not sure you need to allow for
it. If you do, I suspect you'll encourage off-by-one mistakes.
Granted, those mistakes won't result in overruns, but they will
be annoying. Furthermore that will result in different
fixed_string types; will you provide for conversions among them?
(That is, for example, from a fixed_string that adds one to the
capacity to one that doesn't?)

> >(I know there is no make_fixed_string() -- yet -- but such a
> >facility would be appropriate.)
>
> Er... the fixed_string constructors! When you declare the object, you should
> know the size of the buffer you are using, e.g.:
>
> fixed_string< 100 > data;

The problem is that you don't know the length of the string.
That is, with this code:

   char s[] = "1234";

s is a fixed size array of char with five elements. The
programmer didn't have to write:

   char s[5] = "1234";

Instead, the compiler figured out the length.

That's what I'm trying to provide an equivalence for:

    fixed_string_base & s = make_fixed_string("1234");

With that approach, the client doesn't need to precompute the
length of the literal and can rely on the compiler (and template
magic) to deduce it and use it to create a fixed_string<5>.

I've shown returning by value (with the temporary bound to the
reference s), but it could return a smart pointer just as well.

> >I think this clearer reveals that fixed_string's size parameter
                ^^^^^^^
That should have been "clearly."

> >should specify the number of characters. Remember, one can use
> >boost::array to manage a fixed size, non-string buffer. If
> >buffer overrun protection is insufficient in boost::array, that
> >should be fixed (or a new class should be added to Boost). Thus,
> >fixed_string can ignore that usage.
>
> This is not what we are discussing. See above. The need_null name was to
> indicate that an extra charcter be reserved for the null, not whether to add
> a null terminator or not. Sorry for the confusion.

Right, and that's what I was discussing. I showed the typical C
code for creating an array of char for holding a string. In it,
the null is accounted for using "+ 1" rather than being part of
the length "variable." Thus, the length parameter to
fixed_string should also not include the element needed for the
null terminator.

-- 
Rob Stewart                           stewart_at_[hidden]
Software Engineer                     http://www.sig.com
Susquehanna International Group, LLP  using std::disclaimer;

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk