Topic: Defect in the standard string class


Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Sat, 15 Jun 2002 08:39:10 GMT
Raw View
On Tue,  4 Jun 2002 15:11:14 GMT, James Kanze
<kanze@alex.gabi-soft.de> wrote:

(sorry for the late reply)

>|>  Sometime it is impossible for the compiler to detect if the
>|>  bounding check it is necessary or not. (see following)
>
>Certainly.
>
>Of course, this is only a problem if it fails to suppress the bounds
>checking in a critical loop.

Yes.

We all can be very happy if we have operator[] checked and the
compiler eliding the check when it can detect it is unnecessary.

My point is that it is necessary to have ALSO the possibility to
manually turn off the checking where needed.
and i can be happier if this can be possible using the natural syntax
instead of some at() function or more contrivied construct. obviously
i can live with it, but this do not stop me from searching a possible
better standard solution (i remember a pascal compiler who used the
equivalent of C++ #pragma to enable/disable bound checking, i am
unsure if a similar solution can be desirable in C++).

>|>  checking is necessary. the compiler has not sufficient
>|>  informations to decide so it can not elide bound checking at all.

>But in this case, can the bounds checking possibly make a difference?

In at least one specific case i know: yes.

Regards,
Natale Fietta


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 6 Jun 2002 15:16:37 GMT
Raw View
In article <ml6rfucir5ldrh8tqrb1ffd5hvulr04bia@4ax.com>, Steve Heller
<steve@steveheller.com> writes
>>Many establishments loath the concept of a required warning because it
>>means that their well-formed and carefully considered code generates
>>warnings. The issue at hand is a QoI one because any compiler is free to
>>issue a diagnostic when it identifies undefined behaviour.
>
>  Well, in the present case the code is stated by the standard to
>produce undefined behavior. I'm afraid I don't see how such code could
>be "well-formed and carefully considered". But maybe I'm missing
>something.

Because one valid option for an implementor is to define the behaviour.
Code with UB is essentially not portable, but maybe perfectly well, and
predictably, behaved on a specific platform.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Thu, 6 Jun 2002 20:44:50 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:

>In article <ml6rfucir5ldrh8tqrb1ffd5hvulr04bia@4ax.com>, Steve Heller
><steve@steveheller.com> writes
>>>Many establishments loath the concept of a required warning because it
>>>means that their well-formed and carefully considered code generates
>>>warnings. The issue at hand is a QoI one because any compiler is free to
>>>issue a diagnostic when it identifies undefined behaviour.
>>
>>  Well, in the present case the code is stated by the standard to
>>produce undefined behavior. I'm afraid I don't see how such code could
>>be "well-formed and carefully considered". But maybe I'm missing
>>something.
>
>Because one valid option for an implementor is to define the behaviour.
>Code with UB is essentially not portable, but maybe perfectly well, and
>predictably, behaved on a specific platform.

  Ok, I understand. Thanks for the explanation.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Tue, 4 Jun 2002 15:11:14 GMT
Raw View
ros0230@iperbole.bologna.it (Natale Fietta) writes:

|>  On Mon, 27 May 2002 19:53:01 GMT, James Kanze
|>  <kanze@alex.gabi-soft.de> wrote:

|>  >|>  I am sure you know that in some case the added safety is a
|>  >|>  total waste, because the algorithm used make out of bound
|>  >|>  access impossible a-priori

|>  >Except that in such cases, it should be trivial for the compiler
|>  >to optimize the bounds checks out.  I've seen statistics that
|>  >report that the Java compilers manage to suppress more than 90%
|>  >of the bounds checking.  We're not in 1970, after all.

|>  Sometime it is impossible for the compiler to detect if the
|>  bounding check it is necessary or not. (see following)

Certainly.

Of course, this is only a problem if it fails to suppress the bounds
checking in a critical loop.

|>  >Of course, if you happend to do an erase on the vect in the loop,
|>  >and then use the index...

|>  The loop was only an (overly simplified) example, a real situation
|>  i encounter on my work is a const vector used as a look-up table,
|>  in this case the necessity of bound check depend entirely from the
|>  datas used as adresses into the table.  Sometimes they are
|>  generated with an algorithm that ensure only in-bound access
|>  (maybe because it explicitly do preventive bound checking),
|>  sometimes instead datas can be out of the table range so bound
|>  checking is necessary. the compiler has not sufficient
|>  informations to decide so it can not elide bound checking at all.

But in this case, can the bounds checking possibly make a difference?


--=20
James Kanze                                mailto:kanze@gabi-soft.de
Do you need real expertise in C++? in Java? in OO design?
                       I am available, see my CV at www.gabi-soft.de
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)69 63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Tue, 4 Jun 2002 17:16:26 GMT
Raw View
Allan_W@my-dejanews.com (Allan W) writes:

|>  James Kanze <kanze@alex.gabi-soft.de> wrote
|>  > Except that in such cases, it should be trivial for the compiler
|>  > to optimize the bounds checks out. I've seen statistics that
|>  > report that the Java compilers manage to suppress more than 90%
|>  > of the bounds checking. We're not in 1970, after all.

|>  Is this also true in C++? I would hope so.

It depends. The semantics of Java arrays (including bounds checking)
are fully known to the compiler, which helps a lot.  Still, the basis
of the option is simply hoisting a loop invariant out of the loop,
which is a pretty standard optimization in general.  However, the
compiler still has to be able to detect that it *is* a loop
invariant -- this is easy with Java arrays, since their size cannot
change, but a C++ compiler must do enough analysis to determine that
the member variable from which size reads is not changed in the loop.

|>  IIRC, Java has bounds checking as part of the language. (I know
|>  this is true with C#.) So the compiler is free to recognize
|>  patterns such as the code above, and apply bounds checking at the
|>  appropriate times (instead of on every access).

There are still issues as to when the exception is raised.  If I write
something like:

    for ( int i =3D 0 ; i <=3D /* instead of < */ array.size() ; ++ i ) {
        array[ i ] +=3D 1 ;
    }

all of the elements of the array had better be incremented before the
exception is raised.  In this case, the C++ semantics (undefined
behavior) make life easier for the compiler.

|>  By contrast, c++ vectors apply bounds checking WITHIN the code for
|>  operator[]. I don't see how the compiler could optimize away
|>  repeated bounds checking, unless operator[] is inline. (Which,
|>  come to think of it, is a pretty simple solution to the problem,
|>  and my guess would be that operator[] is a good candidate for
|>  inlining anyway.) But with a non-inline operator[] I don't see how
|>  this optimization would be possible -- operator[] can't in general
|>  know where it was called from.

Since std::vector is part of the standard, the compiler can have
built-in knowledge of it.  And as you say, these are the type of small
functions which typically will be inline.

I think that if a compiler wanted to do this type of optimization, the
function size() will be more of a problem -- the compiler *must* be
able to prove that the size of the vector will not change if it is to
hoist the code out of the loop.  The function size() itself is
probably inline, but it returns a member variable, and the compiler
must be able to prove that this member variable is never modified in
the loop.  This is more difficult that it might appear, since any
function that is called *might* access the array through another path,
and change its size.

|>  > |>  In any case i like more a policy based vector, so we can use
|>  > |>  the natural syntax (the operator [] ) in both performance
|>  > |>  critical and not performance critical sections of the code;
|>  > |>  this can also make easier to change from checked to not
|>  > |>  checed version if profiling say this is necessary.

|>  > The problem is that one operator[] in a critical section means
|>  > suppressing bounds checking for all accesses to that array.

|>  Also, with a policy-based approach, operator[] needs to check the
|>  policy at runtime -- this might end up taking the same amount of
|>  time as the bounds check.

I believe the idea was that the policy be specified by some sort of
template magic (traits class, or something similar), to be resolved at
compile time.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Do you need real expertise in C++? in Java? in OO design?
                       I am available, see my CV at www.gabi-soft.de
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)69 63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Thu, 6 Jun 2002 06:02:44 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:

>In article <nv3lfu0d82h51vle2ug7if2ell0dcq4bh5@4ax.com>, Steve Heller
><steve@steveheller.com> writes
>>>Sorry, but I do not think we should be fixing the language this way.
>>>This is a quality of  implementation issue and should be handled that
>>>way (compilers can warn about dangerous uses of the Standard Library)
>>
>>  That would be fine with me. Maybe there should be a specification in
>>the standard of required warnings?
>
>Many establishments loath the concept of a required warning because it
>means that their well-formed and carefully considered code generates
>warnings. The issue at hand is a QoI one because any compiler is free to
>issue a diagnostic when it identifies undefined behaviour.

  Well, in the present case the code is stated by the standard to
produce undefined behavior. I'm afraid I don't see how such code could
be "well-formed and carefully considered". But maybe I'm missing
something.


--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Fri, 31 May 2002 15:58:02 GMT
Raw View
On Wed, 29 May 2002 20:22:08 GMT, Allan_W@my-dejanews.com (Allan W)
wrote:

>> |>  In any case i like more a policy based vector, so we can use the
>> |>  natural syntax (the operator [] ) in both performance critical and
>> |>  not performance critical sections of the code; this can also make
>> |>  easier to change from checked to not checed version if profiling
>> |>  say this is necessary.
>>
>> The problem is that one operator[] in a critical section means
>> suppressing bounds checking for all accesses to that array.
>
>Also, with a policy-based approach, operator[] needs to check the
>policy at runtime -- this might end up taking the same amount of time
>as the bounds check.

This is true only if the checking policy must be changed dinamically,
there is no overhead otherways.
look at this (overly simplified) implementation for example:

class no_bound_checking
{
protected:
    void do_check(size_t, size_t)
    {} //this is empty and inline, so i hope any decent compiler
       //must elide it, optimizing away also function call cost
}

class bound_checking
{
protected:
    void do_check(size_t idx, size_t size)
    {
        //do the check and throw an exception if out of bound
    }
}

class vector<..., class checking_policy = bound_checking>
    : public checking_policy
{
    T& operator[](size_t idx)
    {
        checking_policy::do_check(idx, size());
        //common code
    }
}

Dynamic decision of checking policy can be made this way:
(and this do have the overhead you are talking about)

class runtime_bound_checking
{
private:
    bool need_check;
public:
    void enable_check() { need_check = true; }
    void disable_check() { need_check = false; }
protected:
    runtime_bound_check() : need_check(true) {}
    void do_check(size_t idx, size_t size)
    {
        if (need_check)
        {
            //do the check and trow an exception if out of bound
        }
    }
}

Regards,
Natale Fietta

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: Fri, 31 May 2002 17:49:56 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
> >> 1) It adds complexity to an already overly complex type.

> Allan W <Allan_W@my-dejanews.com> writes
> >Sorry, I just don't see that. As someone else already pointed out,
> >this constructor already exists -- all we're doing is giving one
> >of them a default value.

> Maybe I have lost track. I thought the proposal was to add another ctor
> that took an int as a parameter. If we have some other proposal  now
> could you point me to it.

Well, yes. Going back a few messages in this thread:

On May 16 at 12:08PST, Allan_W@my-dejanews.com (Allan W) wrote:
> |>  On the other hand, the OP suggestion to make string(0) ambiguous
> |>  is a compile-time check, so it will not affect the speed of
> |>  existing (correct) instantiations at all. It seems like a simple
> |>  addition, with limited (but real) advantages and no disadvantages
> |>  to match.  The new constructor might even be useful, especially if
> |>  we combine it with -- was it James Kanze that suggested an
> |>  optional second parameter of type char, to determine what
> |>  character would be replicated?
> |>      std::string stars(4,'*'); // I think it's obvious what this does,
> |>                                // even though it isn't defined yet

And then, on May 22 at 14:15PST,
James Kanze <kanze@alex.gabi-soft.de> wrote:
> You apparently missed my irony.  The standard string class already has
> this constructor.  About all I was suggesting is that the second
> parameter receive a default argument of ' '.  I think we could do
> this, if it makes some people happy, although I don't see a great need
> either.  I *would* want to see some more analysis concerning possible
> ambiguities that this might introduce, however.  (Off hand, I don't
> see any, but any request for a change would have to address the issue,
> and either prove that there aren't, or show why they wouldn't cause a
> problem.)

So, the string constructor that takes (int, charT) would have a default
for the charT. This would allow it to take an int alone, which would
cause INTENTIONAL ambiguity when that form was used. As noted in the
rest of my message, this would (I believe) only "break" code that
currently compiles but has undefined behavior... which is precisely the
goal that Steve Heller (the OP) had in the first place.

Again, I don't see how you can charactarize this as making string
"more complex."

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 31 May 2002 22:01:15 GMT
Raw View
In article <23b84d65.0205310942.997e5b5@posting.google.com>, Allan W
<Allan_W@my-dejanews.com> writes
>So, the string constructor that takes (int, charT) would have a default
>for the charT. This would allow it to take an int alone, which would
>cause INTENTIONAL ambiguity when that form was used.

When the int was a 0 but how do we get ambiguity when the int has any
other value?

Currently:
string s = 5;
doesn't compile but it will under this proposal.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Fri, 31 May 2002 23:58:28 GMT
Raw View
On Mon, 27 May 2002 19:53:01 GMT, James Kanze
<kanze@alex.gabi-soft.de> wrote:

>|>  I am sure you know that in some case the added safety is a total
>|>  waste, because the algorithm used make out of bound access
>|>  impossible a-priori

>Except that in such cases, it should be trivial for the compiler to
>optimize the bounds checks out.  I've seen statistics that report that
>the Java compilers manage to suppress more than 90% of the bounds
>checking.  We're not in 1970, after all.

Sometime it is impossible for the compiler to detect if the bounding
check it is necessary or not. (see following)

>Of course, if you happend to do an erase on the vect in the loop, and
>then use the index...

The loop was only an (overly simplified) example, a real situation i
encounter on my work is a const vector used as a look-up table, in
this case the necessity of bound check depend entirely from the datas
used as adresses into the table.
Sometimes they are generated with an algorithm that ensure only
in-bound access (maybe because it explicitly do preventive bound
checking), sometimes instead datas can be out of the table range so
bound checking is necessary. the compiler has not sufficient
informations to decide so it can not elide bound checking at all.

>|>  In any case i like more a policy based vector, so we can use the
>|>  natural syntax (the operator [] ) in both performance critical and
>|>  not performance critical sections of the code; this can also make
>|>  easier to change from checked to not checed version if profiling
>|>  say this is necessary.

>The problem is that one operator[] in a critical section means
>suppressing bounds checking for all accesses to that array.

Good point.
With a policy based vector we can also implement a runtime flag to
enable/disable bound checking if needed (see my other post on the
subject) but this add an overhead so i do not think this it is a very
good solution.

I am also thinking of something like this:
(i assume the contrary of actual standard for this examaple,
operator[] checked and function at() not checked, as in your
suggestion)

template <typename T>
class unchecked_vector_accessor<T>
{
public:
    unchecked_vector_accessor(std::vector<T>& v) : v_(&v) {}
    T& operator[](size_t idx) { return v_->at(idx); }
private:
    std::vector<T>* v_;
}

void
some_func(std::vector<int>& vect)
{
    if ( vect.size() > 42 )
    {
        unchecked_vector_accessor<int> v(vect);
        v[0] = v[1] = v[2] = 42; //natural syntax, no bound checking
    }
    vect[10] = 0; //natural syntax, with bound checking
}

in this case i see two problems: the overhead of the added indirection
and the dangerous confusion deriving from the fact that the same
vector is accessed using two different names.

Maybe it is not possible to obtain what i want (natural syntax in both
form witout any overhead for unchecked version) if operator[] is
checked by default...

Regards,
Natale Fietta

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Sat, 1 Jun 2002 20:53:24 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:

>In article <23b84d65.0205310942.997e5b5@posting.google.com>, Allan W
><Allan_W@my-dejanews.com> writes
>>So, the string constructor that takes (int, charT) would have a default
>>for the charT. This would allow it to take an int alone, which would
>>cause INTENTIONAL ambiguity when that form was used.
>
>When the int was a 0 but how do we get ambiguity when the int has any
>other value?
>
>Currently:
>string s = 5;
>doesn't compile but it will under this proposal.

  Not if the constructor is explicit, as it is in my xstring class,
for that precise reason. If the existing constructor is not explicit,
then the constructor that takes one argument could be written as a
separate constructor rather than by adding a default argument to the
existing (int, charT) constructor.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sun, 2 Jun 2002 01:04:11 GMT
Raw View
In article <8oogfu070861pbr04auv51pk7sd9p4un3c@4ax.com>, Steve Heller
<steve@steveheller.com> writes
>Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
>
>>In article <23b84d65.0205310942.997e5b5@posting.google.com>, Allan W
>><Allan_W@my-dejanews.com> writes
>>>So, the string constructor that takes (int, charT) would have a default
>>>for the charT. This would allow it to take an int alone, which would
>>>cause INTENTIONAL ambiguity when that form was used.
>>
>>When the int was a 0 but how do we get ambiguity when the int has any
>>other value?
>>
>>Currently:
>>string s = 5;
>>doesn't compile but it will under this proposal.
>
>  Not if the constructor is explicit, as it is in my xstring class,
>for that precise reason. If the existing constructor is not explicit,
>then the constructor that takes one argument could be written as a
>separate constructor rather than by adding a default argument to the
>existing (int, charT) constructor.

Yes, your choice is better than their's but still does not cut it with
me because the above line can be written as:

string s(5);

and those used to being bitten by explicit ctors are quite likely to do
that.

Sorry, but I do not think we should be fixing the language this way.
This is a quality of  implementation issue and should be handled that
way (compilers can warn about dangerous uses of the Standard Library)

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Mon, 3 Jun 2002 04:13:23 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:

>In article <8oogfu070861pbr04auv51pk7sd9p4un3c@4ax.com>, Steve Heller
><steve@steveheller.com> writes
>>Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
>>
>>>In article <23b84d65.0205310942.997e5b5@posting.google.com>, Allan W
>>><Allan_W@my-dejanews.com> writes
>>>>So, the string constructor that takes (int, charT) would have a default
>>>>for the charT. This would allow it to take an int alone, which would
>>>>cause INTENTIONAL ambiguity when that form was used.
>>>
>>>When the int was a 0 but how do we get ambiguity when the int has any
>>>other value?
>>>
>>>Currently:
>>>string s = 5;
>>>doesn't compile but it will under this proposal.
>>
>>  Not if the constructor is explicit, as it is in my xstring class,
>>for that precise reason. If the existing constructor is not explicit,
>>then the constructor that takes one argument could be written as a
>>separate constructor rather than by adding a default argument to the
>>existing (int, charT) constructor.
>
>Yes, your choice is better than their's but still does not cut it with
>me because the above line can be written as:
>
>string s(5);
>
>and those used to being bitten by explicit ctors are quite likely to do
>that.
>
>Sorry, but I do not think we should be fixing the language this way.
>This is a quality of  implementation issue and should be handled that
>way (compilers can warn about dangerous uses of the Standard Library)

  That would be fine with me. Maybe there should be a specification in
the standard of required warnings?

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 3 Jun 2002 14:49:45 GMT
Raw View
In article <nv3lfu0d82h51vle2ug7if2ell0dcq4bh5@4ax.com>, Steve Heller
<steve@steveheller.com> writes
>>Sorry, but I do not think we should be fixing the language this way.
>>This is a quality of  implementation issue and should be handled that
>>way (compilers can warn about dangerous uses of the Standard Library)
>
>  That would be fine with me. Maybe there should be a specification in
>the standard of required warnings?

Many establishments loath the concept of a required warning because it
means that their well-formed and carefully considered code generates
warnings. The issue at hand is a QoI one because any compiler is free to
issue a diagnostic when it identifies undefined behaviour.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: Wed, 29 May 2002 20:22:08 GMT
Raw View
> |>  On Wed, 22 May 2002 16:12:22 CST, James Kanze
> |>  <kanze@alex.gabi-soft.de> wrote:
> |>  >Quite.  In my pre-standard vector classes, operator[] did bounds
> |>  >checking.  If you couldn't afford it, there was a function
> |>  >unsafe at which didn't.

> ros0230@iperbole.bologna.it (Natale Fietta) writes:
> |>  I am sure you know that in some case the added safety is a total
> |>  waste, because the algorithm used make out of bound access
> |>  impossible a-priori, a very simple example is this:
>
> |>  for ( int i = 0; i < vect.size(); ++i )
> |>  {
> |>   //various operations on vect[i]
> |>  }
>
> |>  so in the C++ tradition of "do not pay for what you don't need" i
> |>  think the current status of operator[] (not checked) is correct.
>
James Kanze <kanze@alex.gabi-soft.de> wrote
> Except that in such cases, it should be trivial for the compiler to
> optimize the bounds checks out.  I've seen statistics that report that
> the Java compilers manage to suppress more than 90% of the bounds
> checking.  We're not in 1970, after all.

Is this also true in C++? I would hope so.

IIRC, Java has bounds checking as part of the language. (I know this is
true with C#.) So the compiler is free to recognize patterns such as the
code above, and apply bounds checking at the appropriate times (instead
of on every access).

By contrast, c++ vectors apply bounds checking WITHIN the code for
operator[]. I don't see how the compiler could optimize away repeated
bounds checking, unless operator[] is inline. (Which, come to think of
it, is a pretty simple solution to the problem, and my guess would be
that operator[] is a good candidate for inlining anyway.) But with a
non-inline operator[] I don't see how this optimization would be
possible -- operator[] can't in general know where it was called from.

> |>  In any case i like more a policy based vector, so we can use the
> |>  natural syntax (the operator [] ) in both performance critical and
> |>  not performance critical sections of the code; this can also make
> |>  easier to change from checked to not checed version if profiling
> |>  say this is necessary.
>
> The problem is that one operator[] in a critical section means
> suppressing bounds checking for all accesses to that array.

Also, with a policy-based approach, operator[] needs to check the
policy at runtime -- this might end up taking the same amount of time
as the bounds check.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: Wed, 29 May 2002 20:39:01 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote
> Allan W <Allan_W@my-dejanews.com> writes
> >> I *would* want to see some more analysis concerning possible
> >> ambiguities that this might introduce, however.  (Off hand, I don't
> >> see any, but any request for a change would have to address the issue,
> >> and either prove that there aren't, or show why they wouldn't cause a
> >> problem.)
> >
> >Unlike other proposals, this one seeks to convert some undefined
> >run-time behavior into a compile-time ambiguity. AFAICS, the only
> >problem this would cause is the obvious one: legacy code would break.
> >But not just any legacy code -- only code that, if executed, would
> >have invoked undefined behavior!
>
> other reasons for objecting:
>
> 1) It adds complexity to an already overly complex type.

Sorry, I just don't see that. As someone else already pointed out,
this constructor already exists -- all we're doing is giving one
of them a default value.

> 2) It only solves part of a problem.

Agreed. However, that makes what remains somewhat easier to step
over.

> 3) It introduces a new opportunity for incorrect code to compile to do
> something the programmer did not intend, even though well defined.

If that's true, you've convinced me. But AFAIK, this isn't true.
I could contrive code which:
   * Currently compiles, and (after this change) still would -- but it
     would also work the same way.
   * Currently compiles, but (after this change) would not. (But this
     is the whole point, because that code would be illegal anyway.)
   * Currently does NOT compile, and after this change still wouldn't.

If you can post some example code that currently compiles, and this
change causes a silent change in behavior -- even if it was contrived,
that would probably convince me that the idea was a bad one.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 31 May 2002 00:12:32 GMT
Raw View
In article <23b84d65.0205291208.348916c5@posting.google.com>, Allan W
<Allan_W@my-dejanews.com> writes
>> 1) It adds complexity to an already overly complex type.
>
>Sorry, I just don't see that. As someone else already pointed out,
>this constructor already exists -- all we're doing is giving one
>of them a default value.
Maybe I have lost track. I thought the proposal was to add another ctor
that took an int as a parameter. If we have some other proposal  now
could you point me to it.

>
>> 2) It only solves part of a problem.
>
>Agreed. However, that makes what remains somewhat easier to step
>over.
>
>> 3) It introduces a new opportunity for incorrect code to compile to do
>> something the programmer did not intend, even though well defined.
>
>If that's true, you've convinced me. But AFAIK, this isn't true.
>I could contrive code which:
>   * Currently compiles, and (after this change) still would -- but it
>     would also work the same way.
>   * Currently compiles, but (after this change) would not. (But this
>     is the whole point, because that code would be illegal anyway.)
>   * Currently does NOT compile, and after this change still wouldn't.
>
>If you can post some example code that currently compiles, and this
>change causes a silent change in behavior -- even if it was contrived,
>that would probably convince me that the idea was a bad one.

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Mon, 27 May 2002 19:53:01 GMT
Raw View
ros0230@iperbole.bologna.it (Natale Fietta) writes:

|>  On Wed, 22 May 2002 16:12:22 CST, James Kanze
|>  <kanze@alex.gabi-soft.de> wrote:

|>  >Quite.  In my pre-standard vector classes, operator[] did bounds
|>  >checking.  If you couldn't afford it, there was a function
|>  >unsafe_at which didn't.

|>  >I still think that this is the correct solution -- the natural,
|>  >default way of writing is the safe way, and if you need the extra
|>  >speed, you must explicitly request* it.

|>  I am sure you know that in some case the added safety is a total
|>  waste, because the algorithm used make out of bound access
|>  impossible a-priori, a very simple example is this:

|>  for ( int i =3D 0; i < vect.size(); ++i )
|>  {
|>   //various operations on vect[i]
|>  }

|>  so in the C++ tradition of "do not pay for what you don't need" i
|>  think the current status of operator[] (not checked) is correct.

Except that in such cases, it should be trivial for the compiler to
optimize the bounds checks out.  I've seen statistics that report that
the Java compilers manage to suppress more than 90% of the bounds
checking.  We're not in 1970, after all.

Of course, if you happend to do an erase on the vect in the loop, and
then use the index...

|>  In any case i like more a policy based vector, so we can use the
|>  natural syntax (the operator [] ) in both performance critical and
|>  not performance critical sections of the code; this can also make
|>  easier to change from checked to not checed version if profiling
|>  say this is necessary.

The problem is that one operator[] in a critical section means
suppressing bounds checking for all accesses to that array.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Need real expertise in C++, Java, OO design
                       I am available, see my CV at www.gabi-soft.de
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)69 63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 28 May 2002 00:42:32 GMT
Raw View
In article <23b84d65.0205241623.7f697e@posting.google.com>, Allan W
<Allan_W@my-dejanews.com> writes
>> I *would* want to see some more analysis concerning possible
>> ambiguities that this might introduce, however.  (Off hand, I don't
>> see any, but any request for a change would have to address the issue,
>> and either prove that there aren't, or show why they wouldn't cause a
>> problem.)
>
>Unlike other proposals, this one seeks to convert some undefined
>run-time behavior into a compile-time ambiguity. AFAICS, the only
>problem this would cause is the obvious one: legacy code would break.
>But not just any legacy code -- only code that, if executed, would
>have invoked undefined behavior!

other reasons for objecting:

1) It adds complexity to an already overly complex type.
2) It only solves part of a problem.
3) It introduces a new opportunity for incorrect code to compile to do
something the programmer did not intend, even though well defined.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Fri, 24 May 2002 16:54:10 GMT
Raw View
On Wed, 22 May 2002 16:12:22 CST, James Kanze
<kanze@alex.gabi-soft.de> wrote:

>Quite.  In my pre-standard vector classes, operator[] did bounds
>checking.  If you couldn't afford it, there was a function unsafe_at
>which didn't.
>
>I still think that this is the correct solution -- the natural,
>default way of writing is the safe way, and if you need the extra
>speed, you must explicitly request* it.

I am sure you know that in some case the added safety is a total
waste, because the algorithm used make out of bound access impossible
a-priori, a very simple example is this:

for ( int i = 0; i < vect.size(); ++i )
{
 //various operations on vect[i]
}

so in the C++ tradition of "do not pay for what you don't need" i
think the current status of operator[] (not checked) is correct.

In any case i like more a policy based vector, so we can use the
natural syntax (the operator [] ) in both performance critical and not
performance critical sections of the code; this can also make easier
to change from checked to not checed version if profiling say this is
necessary.

Regards,
Natale Fietta

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: Fri, 24 May 2002 20:09:44 CST
Raw View
> Allan_W@my-dejanews.com (Allan W) writes:
> |>  On the other hand, the OP suggestion to make string(0) ambiguous
> |>  is a compile-time check, so it will not affect the speed of
> |>  existing (correct) instantiations at all. It seems like a simple
> |>  addition, with limited (but real) advantages and no disadvantages
> |>  to match.  The new constructor might even be useful, especially if
> |>  we combine it with -- was it James Kanze that suggested an
> |>  optional second parameter of type char, to determine what
> |>  character would be replicated?
>
> |>      std::string stars(4,'*'); // I think it's obvious what this does,
> |>                                // even though it isn't defined yet

James Kanze <kanze@alex.gabi-soft.de> wrote
> You apparently missed my irony.  The standard string class already has
> this constructor.  About all I was suggesting is that the second
> parameter receive a default argument of ' '.  I think we could do
> this, if it makes some people happy, although I don't see a great need
> either.

You're right -- I must have been asleep, or something.

> I *would* want to see some more analysis concerning possible
> ambiguities that this might introduce, however.  (Off hand, I don't
> see any, but any request for a change would have to address the issue,
> and either prove that there aren't, or show why they wouldn't cause a
> problem.)

Unlike other proposals, this one seeks to convert some undefined
run-time behavior into a compile-time ambiguity. AFAICS, the only
problem this would cause is the obvious one: legacy code would break.
But not just any legacy code -- only code that, if executed, would
have invoked undefined behavior!

The only reason I know of to object, is if you have code like that
which is never reached.

    for (int i=0; i<10; i+=2) {
        if (3==i) {
            string oops(0);
        }
    }

Here's code that used to compile correctly, and the only reason it
wouldn't invoke undefined behavior is that 3==i is always false.
After this change, the above code would no longer compile.

I would expect such code to be exceptionally rare.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Wed, 22 May 2002 16:12:22 CST
Raw View
Allan_W@my-dejanews.com (Allan W) writes:

|>  Consider that C and C++ have always favored speed over safety,
|>  sometimes to ludicrous extents -- would bounds-checking on
|>  std::vector::operator[] really affect performance very much? I
|>  think not -- but if you want bounds-checking, you have to
|>  implement it yourself (use at()).

Quite.  In my pre-standard vector classes, operator[] did bounds
checking.  If you couldn't afford it, there was a function unsafe_at
which didn't.

I still think that this is the correct solution -- the natural,
default way of writing is the safe way, and if you need the extra
speed, you must explicitly request it.

|>  Same thing will apply, rightly or wrongly, to uses of null where
|>  they are currently illegal. If we change std::string(const char*)
|>  to check for a null pointer, that check will take at least one
|>  (and probably two) extra machine cycles -- enough to make some
|>  people complain.

I think that this argument had some weight with regards to the
original C functions, like strlen.  In the case of std::string,
however, we are talking about a class which uses dynamic memory; the
cost of the test is certainly negligible compared to the cost of
allocation.  In this case, performance ISN'T an argument.

I would definitly like to see the behavior defined when a null pointer
is passed.  A null pointer is NOT an empty string, however, and I'm
not fully convinced that in this case it should be treated as one.  I
rather think some sort of runtime_exception would be in order.

The current situation is that it is undefined behavior.
Implementations are thus free to do what they want.  Perhaps before
the next round of standardization, implementations will exist that do
one or the other, and we can argue from experience gained from
existing practice.  (This would also provide concrete information as
to whether the potential runtime cost is affordable.)

|>  On the other hand, the OP suggestion to make string(0) ambiguous
|>  is a compile-time check, so it will not affect the speed of
|>  existing (correct) instantiations at all. It seems like a simple
|>  addition, with limited (but real) advantages and no disadvantages
|>  to match.  The new constructor might even be useful, especially if
|>  we combine it with -- was it James Kanze that suggested an
|>  optional second parameter of type char, to determine what
|>  character would be replicated?

|>      std::string stars(4,'*'); // I think it's obvious what this does,
|>                                // even though it isn't defined yet

You apparently missed my irony.  The standard string class already has
this constructor.  About all I was suggesting is that the second
parameter receive a default argument of ' '.  I think we could do
this, if it makes some people happy, although I don't see a great need
either.  I *would* want to see some more analysis concerning possible
ambiguities that this might introduce, however.  (Off hand, I don't
see any, but any request for a change would have to address the issue,
and either prove that there aren't, or show why they wouldn't cause a
problem.)

--
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Fri, 24 May 2002 00:35:48 GMT
Raw View
James Kanze <kanze@alex.gabi-soft.de> wrote:

>Allan_W@my-dejanews.com (Allan W) writes:
>
>|>  Consider that C and C++ have always favored speed over safety,
>|>  sometimes to ludicrous extents -- would bounds-checking on
>|>  std::vector::operator[] really affect performance very much? I
>|>  think not -- but if you want bounds-checking, you have to
>|>  implement it yourself (use at()).
>
>Quite.  In my pre-standard vector classes, operator[] did bounds
>checking.  If you couldn't afford it, there was a function unsafe_at
>which didn't.
>
>I still think that this is the correct solution -- the natural,
>default way of writing is the safe way, and if you need the extra
>speed, you must explicitly request it.

  I agree.


--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Robert Klemme <bob.news@gmx.net>
Date: Tue, 21 May 2002 18:36:16 GMT
Raw View

Allan W schrieb:
> Consider that C and C++ have always favored speed over safety,
> sometimes to ludicrous extents -- would bounds-checking on
> std::vector::operator[] really affect performance very much?
> I think not -- but if you want bounds-checking, you have to
> implement it yourself (use at()).

well, yes.  doing Java most of the time currently i have a
slightly different mindset.  :-)  i would favour safety.  but -
as you said - this can likely provoke a cryout of those concerned
with speed.  i think it's a cultural difference.  personally i
would not like to go back to the C++ way to approach this.  but i
guess, this is a matter of taste.

> On the other hand, the OP suggestion to make string(0) ambiguous
> is a compile-time check, so it will not affect the speed of existing
> (correct) instantiations at all. It seems like a simple addition,
> with limited (but real) advantages and no disadvantages to match.
> The new constructor might even be useful, especially if we combine
> it with -- was it James Kanze that suggested an optional second
> parameter of type char, to determine what character would be
> replicated?
>
>     std::string stars(4,'*'); // I think it's obvious what this does,
>                               // even though it isn't defined yet

yes, i agree.

regards

 robert

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Robert Klemme <bob.news@gmx.net>
Date: Tue, 14 May 2002 17:56:31 GMT
Raw View

James Kanze schrieb:
> Or more generally, say that all member functions of std::string treat
> null pointers as empty strings.

that's a reasonable option, too.

> It's an arguable point. IMHO, the results are more robust, but a null
> pointer is a singular value, and NOT an empty string, and in many
> cases, just treating the singular value as an empty string is not
> appropriate.

well, you can't have both at the same time - robust treatment or
appropriate treatment.  :-)  that's a decision that has to be
made.  normally i'd opt for the robust variant but i feel, that i
don't overlook all consequences.  i'm sure, other people can
better judge on this.

regards

 robert

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: Thu, 16 May 2002 19:07:12 GMT
Raw View
Robert Klemme <bob.news@gmx.net> wrote in message news:<3CE100F4.73C7DF44@gmx.net>...
> James Kanze schrieb:
> > Or more generally, say that all member functions of std::string treat
> > null pointers as empty strings.
>
> that's a reasonable option, too.
>
> > It's an arguable point. IMHO, the results are more robust, but a null
> > pointer is a singular value, and NOT an empty string, and in many
> > cases, just treating the singular value as an empty string is not
> > appropriate.
>
> well, you can't have both at the same time - robust treatment or
> appropriate treatment.  :-)  that's a decision that has to be
> made.  normally i'd opt for the robust variant but i feel, that i
> don't overlook all consequences.  i'm sure, other people can
> better judge on this.

Consider that C and C++ have always favored speed over safety,
sometimes to ludicrous extents -- would bounds-checking on
std::vector::operator[] really affect performance very much?
I think not -- but if you want bounds-checking, you have to
implement it yourself (use at()).

Same thing will apply, rightly or wrongly, to uses of null where
they are currently illegal. If we change std::string(const char*)
to check for a null pointer, that check will take at least one
(and probably two) extra machine cycles -- enough to make some
people complain.

On the other hand, the OP suggestion to make string(0) ambiguous
is a compile-time check, so it will not affect the speed of existing
(correct) instantiations at all. It seems like a simple addition,
with limited (but real) advantages and no disadvantages to match.
The new constructor might even be useful, especially if we combine
it with -- was it James Kanze that suggested an optional second
parameter of type char, to determine what character would be
replicated?

    std::string stars(4,'*'); // I think it's obvious what this does,
                              // even though it isn't defined yet

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Mon, 13 May 2002 17:22:16 GMT
Raw View
Robert Klemme <robert.klemme@myview.de> writes:

|>  > The mistake is avoidable. That doesn't mean that the library
|>  > should not try and cope correctly if it occurs. The cost for
|>  > doing so is fairly negligible, and the gain in robustness
|>  > appreciable.

|>  true. but then i would favour to change the standard in a way that
|>  it requires std::string((char*) 0) to create an empty string like
|>  std::string();

Or more generally, say that all member functions of std::string treat
null pointers as empty strings.

It's an arguable point. IMHO, the results are more robust, but a null
pointer is a singular value, and NOT an empty string, and in many
cases, just treating the singular value as an empty string is not
appropriate.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Andrew Koenig <ark@research.att.com>
Date: Mon, 13 May 2002 18:06:29 GMT
Raw View
James> |>  true. but then i would favour to change the standard in a way that
James> |>  it requires std::string((char*) 0) to create an empty string like
James> |>  std::string();

James> Or more generally, say that all member functions of std::string
James> treat null pointers as empty strings.

James> It's an arguable point. IMHO, the results are more robust, but
James> a null pointer is a singular value, and NOT an empty string,
James> and in many cases, just treating the singular value as an empty
James> string is not appropriate.

There is another, possibly more serious, problem.

The C++ library has many places aside from the std::string class that
treat pointers to zero-terminated character arrays as strings.  Can it
really be right to require implementations to treat zero pointers as
null strings in some contexts but not others?

I don't think so.  That is, I think that either of the following
alternatives is right:

        1) The implementation is required to treat a zero pointer as a
           null string in EVERY context in which a pointer to a
           zero-terminated character array is used to represent a
           string; or

        2) The implementation is NOT required to treat a zero pointer
           as a null string in ANY context in which a pointer to a
           zero-terminated character array is used to represent a
           string.

What I do not want to see is

        3) The implementation is required to treat a zero pointer as a
           null string in SOME, BUT NOT ALL contexts in which a
           pointer to a zero-terminated character array is used to
           represent a string.

What complicates matters even further is that some of these contexts
are inherited from the C library.  So, for example, if we require
implementations to allow this:

        const char* nullp = 0;
        std::string s(nullp);

then I think we should also require implementations to allow this:

        const char* nullp = 0;
        char s[42];
        std::strcpy(s, nullp);

and this:

        std::printf("%s\n", nullp);

and, for that matter, this:

        std::printf(nullp);

and this:

        FILE* fp = fopen(nullp, "r");

In order to implement such requirements, C++ implementations would
generally have to reimplement significant portions of the C library.
I believe that requiring such reimplementation would be far preferable
to allowing C++ implementations to crash on some uses of nullp but not
others.

--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gabriel Dos Reis <gdr@codesourcery.com>
Date: Mon, 13 May 2002 19:28:56 GMT
Raw View
Andrew Koenig <ark@research.att.com> writes:

[...]

| What complicates matters even further is that some of these contexts
| are inherited from the C library.  So, for example, if we require
| implementations to allow this:
|
|         const char* nullp = 0;
|         std::string s(nullp);
|
| then I think we should also require implementations to allow this:
|
|         const char* nullp = 0;
|         char s[42];
|         std::strcpy(s, nullp);
|
| and this:
|
|         std::printf("%s\n", nullp);
|
| and, for that matter, this:
|
|         std::printf(nullp);
|
| and this:
|
|         FILE* fp = fopen(nullp, "r");
|
| In order to implement such requirements, C++ implementations would
| generally have to reimplement significant portions of the C library.

While agreeing in principle with the above, I have to point out that
C++ _already_ requires to reimplement significant portions (if not
all) of the C library because of the semantics game it plays with <xxx.h>
and corresponding <cxxx> variant :-(  The problem is accute for
"independent" library implementors or implementors targetting many
plateforms where they cannot (reasonably) modify the content of the system
headers which also happen to be the C headers.

As a net effect, most vendors don't do anything with the <xxx.h>
headers, agggravating the incompatibility gap *within* C++ i.e. the
semantics difference between a <xxx.h> is much more than just a scope
issue.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Tue, 14 May 2002 17:52:43 GMT
Raw View
Andrew Koenig <ark@research.att.com> wrote:

>There is another, possibly more serious, problem.
>
>The C++ library has many places aside from the std::string class that
>treat pointers to zero-terminated character arrays as strings.  Can it
>really be right to require implementations to treat zero pointers as
>null strings in some contexts but not others?
>
>I don't think so.  That is, I think that either of the following
>alternatives is right:
>
>        1) The implementation is required to treat a zero pointer as a
>           null string in EVERY context in which a pointer to a
>           zero-terminated character array is used to represent a
>           string; or
>
>        2) The implementation is NOT required to treat a zero pointer
>           as a null string in ANY context in which a pointer to a
>           zero-terminated character array is used to represent a
>           string.
>
>What I do not want to see is
>
>        3) The implementation is required to treat a zero pointer as a
>           null string in SOME, BUT NOT ALL contexts in which a
>           pointer to a zero-terminated character array is used to
>           represent a string.
>
>What complicates matters even further is that some of these contexts
>are inherited from the C library.  So, for example, if we require
>implementations to allow this:
>
>        const char* nullp = 0;
>        std::string s(nullp);
>
>then I think we should also require implementations to allow this:
>
>        const char* nullp = 0;
>        char s[42];
>        std::strcpy(s, nullp);
>
>and this:
>
>        std::printf("%s\n", nullp);
>
>and, for that matter, this:
>
>        std::printf(nullp);
>
>and this:
>
>        FILE* fp = fopen(nullp, "r");
>
>In order to implement such requirements, C++ implementations would
>generally have to reimplement significant portions of the C library.
>I believe that requiring such reimplementation would be far preferable
>to allowing C++ implementations to crash on some uses of nullp but not
>others.

  I prefer alternative 1 over 2, but agree that 2 is better than 3.
C++ is complex enough without additional special cases.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Tue, 14 May 2002 17:54:31 GMT
Raw View
Andrew Koenig <ark@research.att.com> writes:

|>  James> |>  true. but then i would favour to change the standard in
|>  James> |>  a way that it requires std::string((char*) 0) to create
|>  James> |>  an empty string like std::string();

|>  James> Or more generally, say that all member functions of
|>  James> std::string treat null pointers as empty strings.

|>  James> It's an arguable point. IMHO, the results are more robust,
|>  James> but a null pointer is a singular value, and NOT an empty
|>  James> string, and in many cases, just treating the singular value
|>  James> as an empty string is not appropriate.

|>  There is another, possibly more serious, problem.

|>  The C++ library has many places aside from the std::string class
|>  that treat pointers to zero-terminated character arrays as
|>  strings.  Can it really be right to require implementations to
|>  treat zero pointers as null strings in some contexts but not
|>  others?

Consistency is a strong argument, although not necessarily a killer
argument.  If different functions within std::string acted
differently, I'd complain loudly.  On the other hand, I see no
compeling reason to be consistent with what occurs in <string.h>.  In
between, I'm less certain: should filebuf::open be required to cope
somehow with null pointers?

For the moment, I'm not convinced that there is a compelling argument
for allowing null pointers in std::string.  Given this, consistency,
even with <string.h>, weighs in, and may end up the deciding point.
But I'm open to discussion, and will consider the possibility that
there is a compelling argument for.  My opinion on the matter, for the
moment, is a decided maybe.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Robert Klemme <robert.klemme@myview.de>
Date: Fri, 10 May 2002 15:26:53 GMT
Raw View

James Kanze schrieb:
> Or the quality of the documentation of the third party libraries you
> are using:-).

darn!

> The mistake is avoidable.  That doesn't mean that the library should
> not try and cope correctly if it occurs.  The cost for doing so is
> fairly negligible, and the gain in robustness appreciable.

true.  but then i would favour to change the standard in a way
that it requires std::string((char*) 0) to create an empty string
like std::string();

regards

 robert

--=20
Robert Klemme
software engineer
-------------------------------------------------------------------------=
-------
myview technologies GmbH & Co. KG
Lindberghring 1 ~ 33142 B=FCren ~ Germany
Fon: +49-2955-7433-20 Fax: +49-2955-7433-99
-------------------------------------------------------------------------=
-------

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Mon, 6 May 2002 07:52:52 GMT
Raw View
I believe that there is a defect in the std::string class. It allows
the initialization of a string with a constant value 0, even though
the result of doing this is undefined. I see no reason for this
behavior, and believe it should be corrected.

My proposed correction is to add an explicit constructor whose
argument is a number of characters and which creates a string
containing that number of spaces, e.g.,

explicit string(unsigned Length);

This would cause the attempt to create a string with a constant zero
to fail because there would then be two possible matches for the
constant zero value, namely this constructor and the one that takes a
single char* argument. Since this new proposed constructor is
explicit, there is no danger of accidentally assigning a number to a
string without the compiler letting you know you are doing that.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Robert Klemme <robert.klemme@myview.de>
Date: Mon, 6 May 2002 14:53:59 GMT
Raw View

Steve Heller schrieb:
>=20
> I believe that there is a defect in the std::string class. It allows
> the initialization of a string with a constant value 0, even though
> the result of doing this is undefined. I see no reason for this
> behavior, and believe it should be corrected.

the standard says "Requires: s shall not be a null pointer." so
if you violate a precondition you must not be surprised if ugly
things happen.

> My proposed correction is to add an explicit constructor whose
> argument is a number of characters and which creates a string
> containing that number of spaces, e.g.,

why spaces?  why not '\0'?  or 'X'?  apart from that: this would
not resolve the ambiguity of "std::string x( 0 )", would it?

regards

 robert


--=20
Robert Klemme
software engineer
-------------------------------------------------------------------------=
-------
myview technologies GmbH & Co. KG
Lindberghring 1 ~ 33142 B=FCren ~ Germany
Fon: +49-2955-7433-20 Fax: +49-2955-7433-99
-------------------------------------------------------------------------=
-------

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Mon, 6 May 2002 17:12:28 GMT
Raw View
Robert Klemme <robert.klemme@myview.de> writes:

|>  Steve Heller schrieb:

|>  > I believe that there is a defect in the std::string class. It
|>  > allows the initialization of a string with a constant value 0,
|>  > even though the result of doing this is undefined. I see no
|>  > reason for this behavior, and believe it should be corrected.

|>  the standard says "Requires: s shall not be a null pointer." so if
|>  you violate a precondition you must not be surprised if ugly
|>  things happen.

Still, it is an awfully easy mistake to make.

|>  > My proposed correction is to add an explicit constructor whose
|>  > argument is a number of characters and which creates a string
|>  > containing that number of spaces, e.g.,

|>  why spaces?  why not '\0'?  or 'X'?

Because these already exist.  In fact, what he probably wants is that
the second parameter of this constructor default to ' '.

|>  apart from that: this would not resolve the ambiguity of
|>  "std::string x( 0 )", would it?

No.  It would create an ambiguity where there currently isn't one.  So
the mistake would cause a compile time error, and not run-time
undefined behavior.  Still: the specifications for the char const*
constructor are quite clear that a null pointer is not allowed.  Null
pointers have never been allowed for any of the C functions in
<string.h>, either.  So I can't quite imagine anyone passing a null
pointer constant directly to the constructor.  Where the problem
occurs is when some other functions returns a null pointer, which is
then used to create an std::string.  And in that case, the only
solution is a run-time check.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 6 May 2002 18:29:18 GMT
Raw View

Steve Heller wrote:
>
> I believe that there is a defect in the std::string class. It allows
> the initialization of a string with a constant value 0, even though
> the result of doing this is undefined. I see no reason for this
> behavior, and believe it should be corrected.

I also find it annoying, but for a slightly different reason.
I think it should handle null charT* pointers more graciously.

> My proposed correction is to add an explicit constructor whose
> argument is a number of characters and which creates a string
> containing that number of spaces, e.g.,
>
> explicit string(unsigned Length);

I'm not sure how this solves anything.  If you want to make
an empty string (assuming that's what you wanted with the zero
consant), why not just omit the constant and you get that.

If you want to use a non-zero size, then there's already a
constructor that takes a size and an arbitrary character
to initialized the string with.  You could use spaces or nulls
or whatevery you like.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Mon, 6 May 2002 18:55:49 GMT
Raw View
Robert Klemme <robert.klemme@myview.de> wrote:

>
>
>Steve Heller schrieb:
>>
>> I believe that there is a defect in the std::string class. It allows
>> the initialization of a string with a constant value 0, even though
>> the result of doing this is undefined. I see no reason for this
>> behavior, and believe it should be corrected.
>
>the standard says "Requires: s shall not be a null pointer." so
>if you violate a precondition you must not be surprised if ugly
>things happen.

  I'm not surprised by the fact that bad things happen if you
initialize a string with 0. However, I see no reason for that problem
not to be caught by the compiler, so long as the value is actually a
constant 0. My proposal is intended to make the compiler catch it in
that case.

>> My proposed correction is to add an explicit constructor whose
>> argument is a number of characters and which creates a string
>> containing that number of spaces, e.g.,
>
>why spaces?  why not '\0'?  or 'X'?  apart from that: this would
>not resolve the ambiguity of "std::string x( 0 )", would it?

  I don't really care what the characters are that are used to fill in
the string, but spaces seemed to be the most generally useful.
  That aside, the whole point of my proposal is not to resolve the
ambiguity of "std::string x( 0 )", but precisely to make "std::string
x( 0 )" ambiguous. That ambiguity is what causes the compiler to
reject that statement.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Carl Daniel" <cpdaniel@pacbell.net>
Date: Mon, 6 May 2002 20:00:36 GMT
Raw View
"Ron Natalie" <ron@sensor.com> wrote in message
news:3CD6A070.5F50BA9E@sensor.com...
> Steve Heller wrote:
> >
> > I believe that there is a defect in the std::string class. It allows
> > the initialization of a string with a constant value 0, even though
> > the result of doing this is undefined. I see no reason for this
> > behavior, and believe it should be corrected.
>
> I also find it annoying, but for a slightly different reason.
> I think it should handle null charT* pointers more graciously.

Ditto that!  What would be so bad about string str(0) being defined to
create a 0-length string?  I know, I know - it's the old "don't pay for what
you don't use" story - that extra if (p) { } around the guts of the string
constructor is going to consume an extra clock cycle or two.  Yippee :)

-cd


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Mon, 6 May 2002 21:19:41 GMT
Raw View
Ron Natalie <ron@sensor.com> wrote:

>
>
>Steve Heller wrote:
>>
>> I believe that there is a defect in the std::string class. It allows
>> the initialization of a string with a constant value 0, even though
>> the result of doing this is undefined. I see no reason for this
>> behavior, and believe it should be corrected.
>
>I also find it annoying, but for a slightly different reason.
>I think it should handle null charT* pointers more graciously.

  That would be nice too, but it is a different problem.

>> My proposed correction is to add an explicit constructor whose
>> argument is a number of characters and which creates a string
>> containing that number of spaces, e.g.,
>>
>> explicit string(unsigned Length);
>
>I'm not sure how this solves anything.  If you want to make
>an empty string (assuming that's what you wanted with the zero
>consant), why not just omit the constant and you get that.

  I don't want to initialize with a 0 constant. I've done it
accidentally and don't want to have to worry about doing it
accidentally again.

>If you want to use a non-zero size, then there's already a
>constructor that takes a size and an arbitrary character
>to initialized the string with.  You could use spaces or nulls
>or whatevery you like.

  I know that. What I want to do is to prevent a common error that
I've committed myself.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Tue, 7 May 2002 15:50:32 GMT
Raw View
James Kanze <kanze@alex.gabi-soft.de> wrote:

>Robert Klemme <robert.klemme@myview.de> writes:
>
>|>  Steve Heller schrieb:
>
>|>  > I believe that there is a defect in the std::string class. It
>|>  > allows the initialization of a string with a constant value 0,
>|>  > even though the result of doing this is undefined. I see no
>|>  > reason for this behavior, and believe it should be corrected.
>
>|>  the standard says "Requires: s shall not be a null pointer." so if
>|>  you violate a precondition you must not be surprised if ugly
>|>  things happen.
>
>Still, it is an awfully easy mistake to make.

  Which was my point, of course.

>|>  > My proposed correction is to add an explicit constructor whose
>|>  > argument is a number of characters and which creates a string
>|>  > containing that number of spaces, e.g.,
>
>|>  why spaces?  why not '\0'?  or 'X'?
>
>Because these already exist.  In fact, what he probably wants is that
>the second parameter of this constructor default to ' '.

  I'm not sure how useful that would be for purposes other than
disambiguation.

>|>  apart from that: this would not resolve the ambiguity of
>|>  "std::string x( 0 )", would it?
>
>No.  It would create an ambiguity where there currently isn't one.  So
>the mistake would cause a compile time error, and not run-time
>undefined behavior.  Still: the specifications for the char const*
>constructor are quite clear that a null pointer is not allowed.  Null
>pointers have never been allowed for any of the C functions in
><string.h>, either.  So I can't quite imagine anyone passing a null
>pointer constant directly to the constructor.

  I don't have to imagine it. I did it (by accident, of course).

> Where the problem
>occurs is when some other functions returns a null pointer, which is
>then used to create an std::string.  And in that case, the only
>solution is a run-time check.

  That's a different problem from the one I'm trying to solve.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: emarkp@CSUA.Berkeley.EDU (E. Mark Ping)
Date: Tue, 7 May 2002 15:51:12 GMT
Raw View
In article <bSAB8.5934$by2.70880485@newssvr21.news.prodigy.com>,
Carl Daniel <cpdaniel@pacbell.net> wrote:
>Ditto that!  What would be so bad about string str(0) being defined
>to create a 0-length string?  I know, I know - it's the old "don't
>pay for what you don't use" story - that extra if (p) { } around the
>guts of the string constructor is going to consume an extra clock
>cycle or two.  Yippee :)

Indeed we have an important example in "delete" which works properly
if the pointer is null (likely because "free" also has this behavior).
However, I think it makes sense to make string behave in an expected
manner.  Perhaps this is a perfect example for one of A.Alexandrescu's
parameters?
--
Mark Ping
emarkp@soda.CSUA.Berkeley.EDU

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Robert Klemme <robert.klemme@myview.de>
Date: Tue, 7 May 2002 15:53:58 GMT
Raw View

James Kanze schrieb:
> Still, it is an awfully easy mistake to make.

well, that depends on you personal discipline...

> |>  why spaces?  why not '\0'?  or 'X'?
>=20
> Because these already exist.  In fact, what he probably wants is that
> the second parameter of this constructor default to ' '.

:-)

> |>  apart from that: this would not resolve the ambiguity of
> |>  "std::string x( 0 )", would it?
>=20
> No.  It would create an ambiguity where there currently isn't one.  So
> the mistake would cause a compile time error, and not run-time
> undefined behavior.  Still: the specifications for the char const*
> constructor are quite clear that a null pointer is not allowed.  Null
> pointers have never been allowed for any of the C functions in
> <string.h>, either.  So I can't quite imagine anyone passing a null
> pointer constant directly to the constructor.  Where the problem
> occurs is when some other functions returns a null pointer, which is
> then used to create an std::string.  And in that case, the only
> solution is a run-time check.

exactly.  but this should be routinely done (see above).

 robert

--=20
Robert Klemme
software engineer
-------------------------------------------------------------------------=
-------
myview technologies GmbH & Co. KG
Lindberghring 1 ~ 33142 B=FCren ~ Germany
Fon: +49-2955-7433-20 Fax: +49-2955-7433-99
-------------------------------------------------------------------------=
-------

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Juergen Heinzl <juergen@monocerus.manannan.org>
Date: Tue, 7 May 2002 21:31:57 GMT
Raw View
In article <bSAB8.5934$by2.70880485@newssvr21.news.prodigy.com>, Carl Daniel wrote:
> "Ron Natalie" <ron@sensor.com> wrote in message
> news:3CD6A070.5F50BA9E@sensor.com...
>> Steve Heller wrote:
>> >
>> > I believe that there is a defect in the std::string class. It allows
>> > the initialization of a string with a constant value 0, even though
>> > the result of doing this is undefined. I see no reason for this
>> > behavior, and believe it should be corrected.
>>
>> I also find it annoying, but for a slightly different reason.
>> I think it should handle null charT* pointers more graciously.
>
> Ditto that!  What would be so bad about string str(0) being defined to
> create a 0-length string?  I know, I know - it's the old "don't pay for what
> you don't use" story - that extra if (p) { } around the guts of the string
> constructor is going to consume an extra clock cycle or two.  Yippee :)
[-]
I do not agree -- in std::string( 0 ) you pass a null pointer, not
a pointer to an empty string and treating it as such would result
in an ambiguity.

A bit like printf( "%s", NULL ) printing "(null)" or something similar
in C and in some environments as it's an error still and it may result
in anything from nothing to a disaster.

IMHO at most throwing a std::logic_error exception could be a reasonable
thing to do.

IMNSHO errors ought to show up as soon as possible, even if this means
your application to tank pretty quick,
Juergen

--
\ Real name     : Juergen Heinzl       \       no flames      /
 \ EMail Private : juergen@manannan.org \ send money instead /

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 8 May 2002 16:39:29 GMT
Raw View
In article <ojmadu002s1v2f09aiekh6cc6olh06s2nc@4ax.com>, Steve Heller
<steve@steveheller.com> writes
>I believe that there is a defect in the std::string class. It allows
>the initialization of a string with a constant value 0, even though
>the result of doing this is undefined. I see no reason for this
>behavior, and believe it should be corrected.

I tend to agree with you that some undefined behaviour could and should
be eliminated, but technically that is not a defect in the C++ Standard.

>
>My proposed correction is to add an explicit constructor whose
>argument is a number of characters and which creates a string
>containing that number of spaces, e.g.,
>
>explicit string(unsigned Length);

This seems a very heavy-handed way of dealing with a specific case where
a null pointer constant is detrimental. There are quite a few others and
I wish there were a general solution that does not break existing code.
What your solution does is to create a different class of coding
mistakes -- those where the programmer mistakenly calls a constructor
for string with an argument that is convertible to an int. These errors
could be much subtler and less easy to detect at compile time.

BTW your solution only protects against cases where 0 is the null
pointer constant. The cost is that code such as:

int i=0;
std::string s(i);

will compile but provide another corner case that programmers must watch
for at runtime.


>
>This would cause the attempt to create a string with a constant zero
>to fail because there would then be two possible matches for the
>constant zero value, namely this constructor and the one that takes a
>single char* argument. Since this new proposed constructor is
>explicit, there is no danger of accidentally assigning a number to a
>string without the compiler letting you know you are doing that.

But accidental assignment is only one possible cause of error, even
though it is the most obvious.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Wed, 8 May 2002 16:45:25 GMT
Raw View
Robert Klemme <robert.klemme@myview.de> writes:

|>  James Kanze schrieb:
|>  > Still, it is an awfully easy mistake to make.

|>  well, that depends on you personal discipline...

Or the quality of the documentation of the third party libraries you
are using:-).

The mistake is avoidable.  That doesn't mean that the library should
not try and cope correctly if it occurs.  The cost for doing so is
fairly negligible, and the gain in robustness appreciable.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Heller <steve@steveheller.com>
Date: Wed, 8 May 2002 21:37:27 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:

>In article <ojmadu002s1v2f09aiekh6cc6olh06s2nc@4ax.com>, Steve Heller
><steve@steveheller.com> writes
>>I believe that there is a defect in the std::string class. It allows
>>the initialization of a string with a constant value 0, even though
>>the result of doing this is undefined. I see no reason for this
>>behavior, and believe it should be corrected.
>
>I tend to agree with you that some undefined behaviour could and should
>be eliminated, but technically that is not a defect in the C++ Standard.

  I didn't say it was a defect in the standard. I do believe it is a
defect in the string class, though.

>>
>>My proposed correction is to add an explicit constructor whose
>>argument is a number of characters and which creates a string
>>containing that number of spaces, e.g.,
>>
>>explicit string(unsigned Length);
>
>This seems a very heavy-handed way of dealing with a specific case where
>a null pointer constant is detrimental. There are quite a few others and
>I wish there were a general solution that does not break existing code.
>What your solution does is to create a different class of coding
>mistakes -- those where the programmer mistakenly calls a constructor
>for string with an argument that is convertible to an int. These errors
>could be much subtler and less easy to detect at compile time.

 I would be happy if the compiler would warn me about this, but it
doesn't.

>BTW your solution only protects against cases where 0 is the null
>pointer constant. The cost is that code such as:
>
>int i=0;
>std::string s(i);
>
>will compile but provide another corner case that programmers must watch
>for at runtime.

  True, but that's a lot harder mistake to make accidentally, in my
opinion.

>
>>
>>This would cause the attempt to create a string with a constant zero
>>to fail because there would then be two possible matches for the
>>constant zero value, namely this constructor and the one that takes a
>>single char* argument. Since this new proposed constructor is
>>explicit, there is no danger of accidentally assigning a number to a
>>string without the compiler letting you know you are doing that.
>
>But accidental assignment is only one possible cause of error, even
>though it is the most obvious.

And the easiest to do by accident.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]