Topic: defect in std::strtod


Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 6 Mar 2002 19:04:34 GMT
Raw View
> Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote
> > This looks like both a std and lang issue.
> > All the usual strtoX functions are (more or less) like this:
> >
> >
> > X strtoX( const char* , char** )
> >
> > where X is double, int and so on and the char**  gets the position which
> > stopped the scan.

"Mike Wahler" <mkwahler@ix.netcom.com> wrote
> For the integral forms ('strtol()' and 'strtoul()'), there's
> a third argument, the 'radix'.

Not really relevant to Mycroft's point.

> > imho this a minor error: since obviously this char** point to somewhere
> > inside the other argument,
>
> No, it does not.  Why do you think this is 'obvious?'

Because of the definition of these library functions! Specifically:

> The 'char**' parameter represents the address of a pointer
> which is passed by the caller.  (Unless this parameter is
> passed a value of 'NULL') the strto..() functions store the
> address of the byte that stops the parsing in the object this
> pointer points to.

Exactly. This pointer is changed so that it points somewhere
in the first buffer. The first argument is const, so Mycroft feels
that the second parameter should be const as well. More specifically,
he feels that:

> >there should be TWO functions
> >
> > X strtoX( const char* , const char** )
> > X strtoX( char* , char** )

Here, Mycroft goes further by recognizing that we might need
a non-const pointer returned, and suggests allowing that by
overloading the strtoX functions.

> The C library functions are not overloaded.
> They're *C* functions, not C++ functions.

Right. But C++ does overload some C functions -- strchr, strpbrk,
strrchr, strstr, and so on. In each case, the overload has a version
that accepts a const char* and returns a const char*, and a version
that accepts a (non-const) char* and returns a (non-const) char*.
Obviously these overloads don't apply in C, just in C++. This is a
precedent that could have also been applied to the strtoX() functions.

> You do effectively have both forms, though.  If you
> don't want to use the second parameter, pass it
> a value of 'NULL'.

And this is why I believe that you have COMPLETELY missed Mycroft's
point. Not once did he suggest that he didn't want to use the second
parameter! He just feels that it should be const when the first
parameter is const, for reasons of const safety.

...

> The language can protect you from mistakes, but
> not deliberate 'malice'.

Mike, as I said, I believe that you somehow managed to COMPLETELY
miss Mycroft's point. He was already aware of the problems with
overwriting a const char literal, so there was no 'malice.' His
complaint is that these library functions fail to protect us from
mistakes.

Let's make this more concrete.

    void foo(const char*buff) {
        char*x;
        if (strtod(buff,&x,10))
           strcpy(x," < 10.0");
        else
           strcpy(x," > 10.0");
        std::cout << buff << std::endl;
    }
    int main() {
        const char value[] = "0.11, 1.10, 11.0";
        foo(value);
        foo(value + 6);
        foo(value + 12);
    }

The programmer may have intended this program to write:
    0.11 < 10.0
    1.10 < 10.0
    11.0 > 10.0
But that's not what he got. In a debugger, he eventually discovers
that the contents of value[] have changed. This is a shock, because
he's been rigorous about const-correctness and no const_casts have
been used... what went wrong?

The answer, of course, is that strtod() accepts a const pointer and
returns a non-const pointer into that same buffer. This is Mycroft's
complaint, at least as I understand it.

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Roger Orr" <rogero@howzatt.demon.co.uk>
Date: Sun, 3 Mar 2002 09:09:31 GMT
Raw View
Adam H. Peterson wrote in message ...
><snip>
>> > Being a minimalist, I say there should be one function...
>> >
>> > X strtoX(char const*,char const**);
>> >
>>
>> Possibly - but this reduces functionality.
>> This current strtoX works where people want to _modify_ the input string,
>> which is non-const.
[snip]
>This doesn't actually prevent you from doing this.  You can still modify
the
>buffer as follows:


Sorry, I wasn't clear enough in my first posting.  Your example code does
provide the same functionality as my example - but it requires a code
change.  I was (and am!) concerned about existing code - if a proposed
change breaks existing code there needs to be strong justification.  This is
even more the case with functions like strtoX whose basic signatures are
inherited from C.

I think one function may be the best solution in the abstract - but now it
is too late.
--
Roger Orr
MVP in C++ at www.brainbench.com


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Mon, 4 Mar 2002 15:31:29 GMT
Raw View
> > As I said before, M****soft is far more correct: when you post a
> > bug, they don't ask you to own their product.
>
> I think you have misunderstood the situation, and I also think
> you are comparing apples to kangaroos.


No, I think you misunderstand the situation.

first, it's a matter of principle.
But if I submit an error to the std comitee, I'm not likely to have any
personal benefit: provided I'm right, the correction will possibly appear in
c++ new draft in year 200X, and compilers will implement it in year 20YX, so
basically I've got to find a workaround on my own.

second, it's a matter also of cost.
$19 is not a large sum, but it's strictly greater than 0 (and if you add the
cost of laser-printing it...), and if you add this to the previous point,
you get it's not worthy to post a defect.
M****soft compiler costs something more than that, but I didn't pay for it:
it's a working instrument supplied by the company I work in.
Nonetheless, they do verify all bug reports they get (I don't care if they
are paid for this or not: I just note they do) and I can see they provide a
lot of patches, fixes, etc.etc.
So the basic economic ratio (cost/utility) is +infinite against
0/(0+positive_random), which at most is undefined.


third, it's a matter of common sense.
if you really care about something (and you said you do) AND you can easily
fill-in the details, then you loose more time making sterile objections than
checking a posting (which, as far as I read, is not total nonsense)

Of course, I'm open to any suggestion about the MATTER of the posting.

--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Mon, 4 Mar 2002 15:55:57 GMT
Raw View
> >
> >  mystrtod( msg, &msg );
> >  mystrtod( msg2, &msg2 );
>
>    mystrtod( msg, &msg2 ); // silently uses your 'deprecated' API
>    *msg2 = 'X';
>

I know you *can* still use the old version, but in the thread I read
messages worried about compatibility.
the idea of the message was: the compiler does distinguish F(const char*,
char**) from F(const char*, const char**), so *in abstract* the problem
might be solved by simply overloading strtod. if you put several strtod's,
then you can call whatever you prefer.
--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mike Wahler" <mkwahler@ix.netcom.com>
Date: Thu, 21 Feb 2002 16:46:16 CST
Raw View
Pete Becker <petebecker@acm.org> wrote in message
news:3C7421FE.E5E970FB@acm.org...
> Mike Wahler wrote:
> >
> > OK.  But what I was trying to determine was whether my
> > assesment of OP's code was accurate, i.e. is the compiler
> > wrong, or did OP just write UB code?  (I called it the latter)
>
> I thought I posted a followup to my message, but I don't see it, and it
> looks like you didn't, either. <g>
>
> >
> > What I'm calling UB is this (which imo is essentially what OP did):
> >
> > const char array[] = "ABC";
> > char *p = array;
> > *p = 'X';
> >
>
> That's a bit different from what the original code did: the assignment
> to 'p' is illegal. If you add a cast the behavior becomes undefined. The
> compiler could put array in writable memory, or it could put it in
> read-only memory.

Yes, I realize it's a bit different, I was trying (in a
simple way) to 'simulate' the passing of a 'char*'  argument
for a 'const char*' parameter.

>
> The original program does essentially the same thing,

Yes, that's my point. :-)

>but without a cast
> and non-locally (i.e. you can't tell from looking at the function
> overwrite whether the function will succeed, since that depends on
> whether the char array that is passed to it is writable).

The array whose address he passed was designated as 'const'
which is why I thought 'undefined'.

-Mike



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mike Wahler" <mkwahler@ix.netcom.com>
Date: Thu, 21 Feb 2002 16:46:23 CST
Raw View
Ron Natalie <ron@sensor.com> wrote in message
news:3C73DE20.E245A194@sensor.com...
>
>
> Mike Wahler wrote:
> >
> > The C library functions are not overloaded.
> > They're *C* functions, not C++ functions.
>
> There is precedence for providing additional overloads of C funtions.
> There are a bunch in cmath, and also things like memchr.

I spoke too soon.  I stand corrected. :-)

-Mike



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: Thu, 21 Feb 2002 16:46:44 CST
Raw View
"James Kuyper Jr." <kuyper@wizard.net> writes:
>Mike Wahler wrote:
>> Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote:
>> >there should be TWO functions
>> >
>> > X strtoX( const char* , const char** )
>> > X strtoX( char* , char** )
>....
>> The language can protect you from mistakes, but
>> not deliberate 'malice'.
>
>But this is code that could result from a mistake; not in a case this
>simple, obviously, but in more complicated cases that depend upon the
>same mechanism. I prefer that the language be written to make this
>mistake produce a diagnostic. The suggested change to the function's
>signature would seem to have that effect, at no particular cost that I
>can see.

There are backwards compatibility issues with overloading strtod() like
this that don't arise for strstr().

For strstr(), carefully-written existing code would have assigned the
result to a `char *' variable only if the second argument had type
`char *', rather than `const char *'.  So the change from C's single
version to C++'s overloaded version of strstr() would require no change
in carefully-written existing code.

But for strtod(), any code that calls it must pass a pointer of type
`char **' as the second argument, even when the first argument has
type `const char *' rather than `char *'.  So all existing code which
contains calls to strtod() where the first argument has type `const char *'
would have to change.

The costs of fixing all that existing code might well outweigh the benefit.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Fri, 22 Feb 2002 16:17:09 GMT
Raw View
what about providing more than one function?
the compiler is smart enough to distinguish between a const and non-const
char**.



double mystrtod(char* line, char** ptr)
{
 *ptr = line+1;
 return 0;
}

double mystrtod(const char* line, const char** ptr)
{
 *ptr = line+1;
 return 0;
}

double mystrtod(const char* line, char** ptr)    // deprecated
{
 *ptr = (char*)(line+1);
 return 0;
}


int main(int argc, char* argv[])
{

 const char m1[] = "const message";
 char m2[] = "non const message";

 const char* msg = m1;
 char* msg2 = m2;

 mystrtod( msg, &msg );
 mystrtod( msg2, &msg2 );

 return 0;
}


--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes
>
> There are backwards compatibility issues with overloading strtod() like
> this that don't arise for strstr().
>
> [...]

> type `const char *' rather than `char *'.  So all existing code which
> contains calls to strtod() where the first argument has type `const char
*'
> would have to change.
>
> The costs of fixing all that existing code might well outweigh the
benefit.
>


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: kanze@gabi-soft.de (James Kanze)
Date: Fri, 22 Feb 2002 16:26:17 GMT
Raw View
Martin von Loewis <loewis@informatik.hu-berlin.de> wrote in message
news:<j4it8sv9pw.fsf@informatik.hu-berlin.de>...
> "Mike Wahler" <mkwahler@ix.netcom.com> writes:

> > > imho this a minor error: since obviously this char** point to
> > > somewhere inside the other argument,

> > No, it does not.  Why do you think this is 'obvious?'

> Because the language specification says so. The second argument to
> strtod really is an output parameter; the pointer being put out is
> somewhere into the string that was the input argument.

> > > X strtoX( const char* , const char** )
> > > X strtoX( char* , char** )

> > The C library functions are not overloaded.
> > They're *C* functions, not C++ functions.

> They are C++ functions, as they are part of the C++ standard. They
> are extern "C" (i.e. they have "C" linkage), but they are still part
> of the C++ language.

> Of course, you cannot overload functions that have "C" linkage, so
> one of the functions needs to have C++ linkage. If that proposal is
> implemented, then most likely the new function would get C++
> linkage.

Since both of the functions would be new (and different from the C
function), they would probably both have C++ linkage.  In addition,
the C function must disappear; basically, when compiling C, you see:
    extern double strtod( char const*, char** ) ;
and when compiling C++:
    extern double strtod( char*, char** );
    extern double strtod( char const*, char const** );

A typical implementation might be something like:

    extern double __strtod( char const*, char* ) ;
    #ifndef __cplusplus
    extern double strtod( char const*, char* ) ;
    #define strtod( s, e ) __strtod( s, e )
    #else
    inline double strtod( char* s, char** e )
    {
        return __strtod( s, e );
    }
    inline double strtod( char const* s, char const** e )
    {
        return __strtod( s, const_cast< char** >( e ) ) ;
    }
    #endif

--
James Kanze                                   mailto:kanze@gabi-soft.de
Beratung in objektorientierer Datenverarbeitung --
                             -- Conseils en informatique orient   e objet
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany, T   l.: +49 (0)69 19 86 27

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Louis Lavery" <Louis@devilsChimney.co.uk>
Date: Sun, 24 Feb 2002 16:19:56 GMT
Raw View
Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote in message
news:DK8c8.16574$8F6.698472@twister2.libero.it...
> This looks like both a std and lang issue.
> All the usual strtoX functions are (more or less) like this:
>
>
> X strtoX( const char* , char** )
>
> where X is double, int and so on and the char**  gets the position which
> stopped the scan.
> imho this a minor error: since obviously this char** point to somewhere
> inside the other argument, there should be TWO functions

I see it as a major error, it comprimises const correctness.

Being a minimalist, I say there should be one function...

X strtoX(char const*,char const**);

Louis


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Mon, 25 Feb 2002 16:17:14 GMT
Raw View
>
> I see it as a major error, it comprimises const correctness.
>
> Being a minimalist, I say there should be one function...
>
> X strtoX(char const*,char const**);
>
> Louis

Thanks for your... support.
If anybody of you thinks the problem is worthy attention of std comitee, you
could forward the message as a defect report.
It looks like I'm not allowed to do this, since I don't own a copy of the
standard.
As I said before, M****soft is far more correct: when you post a
bug, they don't ask you to own their product.

Imho the best workaround, as someone posted in this thread, is the #ifdef
__cplusplus .... #else ... #endif, so the defect might already have a
"proposed solution"
--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Steve Clamage <clamage@eng.sun.com>
Date: Mon, 25 Feb 2002 18:48:19 GMT
Raw View
On Mon, 25 Feb 2002, Mycroft Holmes wrote:
> Thanks for your... support.
> If anybody of you thinks the problem is worthy attention of std comitee, you
> could forward the message as a defect report.
> It looks like I'm not allowed to do this, since I don't own a copy of the
> standard.
> As I said before, M****soft is far more correct: when you post a
> bug, they don't ask you to own their product.

I think you have misunderstood the situation, and I also think
you are comparing apples to kangaroos.

Microsoft is a vendor of commercial software. They have a large
customer support organization, paid for out of the money they
make selling products.

The C++ standard is produced by volunteers who not only donate
their time, but pay an annual fee for the privilege of donating
that time.

Nonetheless, the C++ standards committee has gone to considerable
trouble to provide avenues by which anyone may present defect
reports (DRs). We ask only that you do some minimal homework
first, to reduce the waste of our own (volunteered) time, as
well as your time.

1. Buy or borrow a copy of the actual standard, to be sure you
are addressing a real issue, not a phantom issue that has long
since been resolved.  The standard can be downloaded online for
for US $19, less than half the cost of a typical C++ book.
Because the standard is so inexpensive, it is likely that you
know someone who has a copy you could look at.

2. Check the issues lists posted on a free public web site to
be sure your issue is a new one.

3. If you think you have found a new defect, send the DR to this
newsgroup with references to the sections of the standard that
are involved.

Details are in the FAQ list for this newsgroup.

Once you have sent a DR to this newsgroup, it will automatically
be forwarded to the C++ Committee, will appear in the public
issues lists, and will be dealt with by the committee.

--
Steve Clamage, stephen.clamage@sun.com

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: rogero@howzatt.demon.co.uk (Roger Orr)
Date: Mon, 25 Feb 2002 20:50:57 GMT
Raw View
"Mycroft Holmes" <holmes@technologist.REMOVEME.com> wrote in message news:<kund8.4762$v7.216395@twister1.libero.it>...
> what about providing more than one function?
> the compiler is smart enough to distinguish between a const and non-const
> char**.

Alas, you'd then be back with the original fault - non const-correct code :(

[snip]
> double mystrtod(const char* line, char** ptr)    // deprecated
[snip]
>  const char m1[] = "const message";
>  char m2[] = "non const message";
>
>  const char* msg = m1;
>  char* msg2 = m2;
>
>  mystrtod( msg, &msg );
>  mystrtod( msg2, &msg2 );

   mystrtod( msg, &msg2 ); // silently uses your 'deprecated' API
   *msg2 = 'X';

--
Roger Orr
MVP in C++ at www.brainbench.com

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Tue, 26 Feb 2002 17:38:37 GMT
Raw View
this is just an example, but when I rewrote my own strtoX functions, I had
them "return" a size_t with the number of chars used, rather then the
pointer. this is in concept simpler, and it allows the caller to update the
pointer, whatever modifier it has, const or not.

double my_strtod(const char* text, size_t* size);

Just to remark that no problem is unsolvable.
 --
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes

>
> There are backwards compatibility issues with overloading strtod() like
> this that don't arise for strstr().
>


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: rogero@howzatt.demon.co.uk (Roger Orr)
Date: Tue, 26 Feb 2002 18:05:17 GMT
Raw View
"Louis Lavery" <Louis@devilsChimney.co.uk> wrote in message news:<1014540296.20294.0.nnrp-13.9e989763@news.demon.co.uk>...
> Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote in message
> news:DK8c8.16574$8F6.698472@twister2.libero.it...
> > This looks like both a std and lang issue.
> > All the usual strtoX functions are (more or less) like this:
> >
> >
> > X strtoX( const char* , char** )
> >
> > where X is double, int and so on and the char**  gets the position which
> > stopped the scan.
> > imho this a minor error: since obviously this char** point to somewhere
> > inside the other argument, there should be TWO functions
>
> I see it as a major error, it comprimises const correctness.
>
> Being a minimalist, I say there should be one function...
>
> X strtoX(char const*,char const**);
>

Possibly - but this reduces functionality.
This current strtoX works where people want to _modify_ the input string,
which is non-const.  As a slightly contrived example:-

   void doit(char *mybuffer) {
     char *firstInvalid;
     strtoX(mybuffer, &firstInvalid );
     *firstInvalid = '\0';
  }

What is wanted is two flavours - one for const char pointers and one for non-const.
--
Roger Orr
MVP in C++ at www.brainbench.com

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Adam H. Peterson" <ahp6@email.byu.edu>
Date: Wed, 27 Feb 2002 06:32:59 GMT
Raw View
<snip>
> > Being a minimalist, I say there should be one function...
> >
> > X strtoX(char const*,char const**);
> >
>
> Possibly - but this reduces functionality.
> This current strtoX works where people want to _modify_ the input string,
> which is non-const.  As a slightly contrived example:-
>
>    void doit(char *mybuffer) {
>      char *firstInvalid;
>      strtoX(mybuffer, &firstInvalid );
>      *firstInvalid = '\0';
>   }
>
> What is wanted is two flavours - one for const char pointers and one for
non-const.

This doesn't actually prevent you from doing this.  You can still modify the
buffer as follows:

    void doit(char *mybuffer) {
      char *firstInvalid;
      strtoX(mybuffer, &firstInvalid );
      mybuffer[firstInvalid-mybuffer] = '\0';
   }

Perhaps a bit kludgey, but it works.  I would hope (probably
unrealistically) that a compiler could optimize this to the original form
after verifying const correctness.  Personally, I like Mycroft's idea of
returning an offset by pointer, but we probably couldn't get the standard
changed to accomodate it.  We'd have to change the C standard and it would
break a lot of existing code (unless you provide it as an overload, which
won't work in C).

You could still implement your overload given the first.

inline X strtoX(char *buffer, char **new_buffer) {
    char const *c_new_buffer=buffer;
    X x=strtoX(c_new_buffer, &c_new_buffer);
    *new_buffer=buffer[c_new_buffer-buffer];
    return x;
}

Of course, I may be way off base here.  Please correct me if I am.




---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Adam H. Peterson" <ahp6@email.byu.edu>
Date: Wed, 27 Feb 2002 10:51:28 GMT
Raw View
Just a correction:

>     void doit(char *mybuffer) {
>       char *firstInvalid;

The above line should be:
        char const *firstInvalid;

>       strtoX(mybuffer, &firstInvalid );
>       mybuffer[firstInvalid-mybuffer] = '\0';
>    }



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Tue, 19 Feb 2002 09:50:19 CST
Raw View
This looks like both a std and lang issue.
All the usual strtoX functions are (more or less) like this:


X strtoX( const char* , char** )

where X is double, int and so on and the char**  gets the position which
stopped the scan.
imho this a minor error: since obviously this char** point to somewhere
inside the other argument, there should be TWO functions

X strtoX( const char* , const char** )
X strtoX( char* , char** )



the following example overwrites a constant string using strtod.




#include <stdlib.h>


void overwrite(const char* line)
{
 char* x;
 strtod(line, &x);
 *x = 'A';
}



int main(int argc, char* argv[])
{
 const char message[] = "message";
 overwrite(message);
 return 0;
}


--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes




======================================= MODERATOR'S COMMENT:

Since this submission does not follow the format of a Defect Report,
it is being treated as an ordinary posting.  If you intended it to be
a Defect Report, please read the instructions in the comp.std.c++
FAQ, and resubmit.
---
Steve Clamage, stephen.clamage@sun.com

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Tue, 19 Feb 2002 23:08:32 GMT
Raw View
This looks like both a std and lang issue.
All the usual strtoX functions are (more or less) like this:


X strtoX( const char* , char** )

where X is double, int and so on and the char**  gets the position which
stopped the scan.
imho this a minor error: since obviously this char** point to somewhere
inside the other argument, there should be TWO functions

X strtoX( const char* , const char** )
X strtoX( char* , char** )



the following example overwrites a constant string using strtod.




#include <stdlib.h>


void overwrite(const char* line)
{
 char* x;
 strtod(line, &x);
 *x = 'A';
}



int main(int argc, char* argv[])
{
 const char message[] = "message";
 overwrite(message);
 return 0;
}


--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mike Wahler" <mkwahler@ix.netcom.com>
Date: Wed, 20 Feb 2002 00:30:50 GMT
Raw View
Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote in message
news:DK8c8.16574$8F6.698472@twister2.libero.it...
> This looks like both a std and lang issue.
> All the usual strtoX functions are (more or less) like this:
>
>
> X strtoX( const char* , char** )
>
> where X is double, int and so on and the char**  gets the position which
> stopped the scan.
> imho this a minor error: since obviously this char** point to somewhere
> inside the other argument, there should be TWO functions
>
> X strtoX( const char* , const char** )
> X strtoX( char* , char** )
>
>
>
> the following example overwrites a constant string using strtod.
>
>
>
>
> #include <stdlib.h>
>
>
> void overwrite(const char* line)
> {
>  char* x;
>  strtod(line, &x);
>  *x = 'A';

In addition to my other remarks, note that this
statement produces 'undefined behavior.'  (By
attempting to modify const storage.)

Once you're in the realm of 'undefined behavior,'
the language standard imposes absolutely no requirements
or constraints upon the resultant behavior.  This could
be 'seems to work', a 'seg fault', 'access violation,'
a crash, or anything else.

The 'defect' is not in the language, but in your code.


-Mike



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mike Wahler" <mkwahler@ix.netcom.com>
Date: Wed, 20 Feb 2002 00:56:29 GMT
Raw View
Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote in message
news:DK8c8.16574$8F6.698472@twister2.libero.it...
> This looks like both a std and lang issue.
> All the usual strtoX functions are (more or less) like this:
>
>
> X strtoX( const char* , char** )
>
> where X is double, int and so on and the char**  gets the position which
> stopped the scan.

For the integral forms ('strtol()' and 'strtoul()'), there's
a third argument, the 'radix'.

> imho this a minor error: since obviously this char** point to somewhere
> inside the other argument,

No, it does not.  Why do you think this is 'obvious?'

The 'char**' parameter represents the address of a pointer
which is passed by the caller.  (Unless this parameter is
passed a value of 'NULL') the strto..() functions store the
address of the byte that stops the parsing in the object this
pointer points to.

>there should be TWO functions
>
> X strtoX( const char* , const char** )
> X strtoX( char* , char** )

The C library functions are not overloaded.
They're *C* functions, not C++ functions.

You do effectively have both forms, though.  If you
don't want to use the second parameter, pass it
a value of 'NULL'.

>
>
>
> the following example overwrites a constant string using strtod.
> #include <stdlib.h>
>
>
> void overwrite(const char* line)
> {
>  char* x;
>  strtod(line, &x);

This statement calls 'strtod()', which parses the characters
starting at address contained in 'line'.  'strtod()' stops parsing
when it encounters an invalid character, and stores the address
of this character in 'x', and discards the type 'double'
result.

>  *x = 'A';

This statement replaces the character pointed to by
'x'  with the character 'A'.  You've intentionally
circumvented the 'constness' of the characters pointed
to by 'line'.

You got what you asked for. :-)

The language can protect you from mistakes, but
not deliberate 'malice'.

> }
>
>
>
> int main(int argc, char* argv[])
> {
>  const char message[] = "message";
>  overwrite(message);
>  return 0;
> }


-Mike


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Wed, 20 Feb 2002 01:11:09 GMT
Raw View
Mike Wahler wrote:
>
> > void overwrite(const char* line)
> > {
> >  char* x;
> >  strtod(line, &x);
> >  *x = 'A';
>
> In addition to my other remarks, note that this
> statement produces 'undefined behavior.'  (By
> attempting to modify const storage.)

That's the point: strtod converted a const char* into a char*. We fixed
that for memchr, strchr, strrchr, and strstr. (And maybe a few others).
If the signature of strtod were changed to

strtod(const char *, const char **)

then the call wouldn't be legal.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Stephen Howe" <NOSPAMsjhowe@dial.pipex.com>
Date: Wed, 20 Feb 2002 13:44:15 GMT
Raw View
> > X strtoX( const char* , const char** )
> > X strtoX( char* , char** )
>
> The C library functions are not overloaded.
> They're *C* functions, not C++ functions.

Is that so?
I have a section in the C standard 21.4 "Null terminated sequence utilities"
where many of the memxxx() and strxxx() functions in the ISO C library are
overloaded. e.g.

const char * strchr(const char *s, int c);
char * strchr(char *s, int c);

Given these can be, why not strtol, strtoul() & strtod() ?

Stephen Howe


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "John R. Antley" <jrantley@mindspring.com>
Date: Wed, 20 Feb 2002 15:11:47 GMT
Raw View
Mike Wahler wrote:

> <snip>
> >
> > the following example overwrites a constant string using strtod.
> > #include <stdlib.h>
> >
> >
> > void overwrite(const char* line)
> > {
> >  char* x;
> >  strtod(line, &x);
>
> This statement calls 'strtod()', which parses the characters
> starting at address contained in 'line'.  'strtod()' stops parsing
> when it encounters an invalid character, and stores the address
> of this character in 'x', and discards the type 'double'
> result.
>
> >  *x = 'A';
>
> This statement replaces the character pointed to by
> 'x'  with the character 'A'.  You've intentionally
> circumvented the 'constness' of the characters pointed
> to by 'line'.
>
> You got what you asked for. :-)
>
> The language can protect you from mistakes, but
> not deliberate 'malice'.

True.  Proof that "const-correctness" is like the lock on your front door.
More for honest people than those who want to break the rules.
Unfortunately, it also sometimes stands in the way of honest people who are
trying to get work done and so the right thing at the same time.


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Michiel.Salters@cmg.nl (Michiel Salters)
Date: Wed, 20 Feb 2002 15:12:12 GMT
Raw View
"Mike Wahler" <mkwahler@ix.netcom.com> wrote in message news:<a4upk8$8s7$1@slb2.atl.mindspring.net>...
> Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote in message
> news:DK8c8.16574$8F6.698472@twister2.libero.it...
> > This looks like both a std and lang issue.
> > All the usual strtoX functions are (more or less) like this:
> >
> > X strtoX( const char* , char** )
> >
> > where X is double, int and so on and the char**  gets the position which
> > stopped the scan.

> > imho this a minor error: since obviously this char** point to somewhere
> > inside the other argument,
>
> No, it does not.  Why do you think this is 'obvious?'
>
> The 'char**' parameter represents the address of a pointer
> which is passed by the caller.

The address of a T is stored in a T*. So if the address of a const char*
needs to be stored, it needs to be stored in a const char**. The function
incorrectly attempts to store a const char** in an char**. Obvious.
( The correct statement should be that *second_arg points into the
  first array, not second_arg itself )

> >there should be TWO functions
> >
> > X strtoX( const char* , const char** )
> > X strtoX( char* , char** )
>
> The C library functions are not overloaded.
> They're *C* functions, not C++ functions.

Not when they're in a C++ program. The C library functions were
modified for inclusion in C++, as Pete Becker pointed out.

> You do effectively have both forms, though.  If you
> don't want to use the second parameter, pass it
> a value of 'NULL'.

That's a whole different story. You still need a function taking
const char* and one taking char*.

> > the following example overwrites a constant string using strtod.
> > #include <stdlib.h>
> >
> > void overwrite(const char* line)
> > {
> >  char* x;
> >  strtod(line, &x);
>
> This statement calls 'strtod()', which parses the characters
> starting at address contained in 'line'.  'strtod()' stops parsing
> when it encounters an invalid character, and stores the address
> of this character in 'x', and discards the type 'double'
> result.
>
> >  *x = 'A';
>
> This statement replaces the character pointed to by
> 'x'  with the character 'A'.  You've intentionally
> circumvented the 'constness' of the characters pointed
> to by 'line'.
>
> The language can protect you from mistakes, but
> not deliberate 'malice'.

Sure it can protect you against these kinds of mistakes.
That's exactly what the proposal is about.

I'm not sure about the difference between a lang issue and a
std issue, though ? It looks like a DR for the LWG
Regards,
--
Michiel Salters

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mike Wahler" <mkwahler@ix.netcom.com>
Date: Wed, 20 Feb 2002 15:23:50 GMT
Raw View
Pete Becker <petebecker@acm.org> wrote in message
news:3C72F427.29A9E875@acm.org...
> Mike Wahler wrote:
> >
> > > void overwrite(const char* line)
> > > {
> > >  char* x;
> > >  strtod(line, &x);
> > >  *x = 'A';
> >
> > In addition to my other remarks, note that this
> > statement produces 'undefined behavior.'  (By
> > attempting to modify const storage.)
>
> That's the point: strtod converted a const char* into a char*.

So is this a constraint violation or not?
I understand it to be merely 'undefined behavior'.
Can you confirm this?


> We fixed
> that for memchr, strchr, strrchr, and strstr. (And maybe a few others).
> If the signature of strtod were changed to
>
> strtod(const char *, const char **)
>
> then the call wouldn't be legal.

Right.

-Mike



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: Wed, 20 Feb 2002 15:39:06 GMT
Raw View
"Mike Wahler" <mkwahler@ix.netcom.com> writes:

>
> > imho this a minor error: since obviously this char** point to somewhere
> > inside the other argument,
>
> No, it does not.  Why do you think this is 'obvious?'

Because the language specification says so. The second argument to
strtod really is an output parameter; the pointer being put out is
somewhere into the string that was the input argument.

> > X strtoX( const char* , const char** )
> > X strtoX( char* , char** )
>
> The C library functions are not overloaded.
> They're *C* functions, not C++ functions.

They are C++ functions, as they are part of the C++ standard. They are
extern "C" (i.e. they have "C" linkage), but they are still part of
the C++ language.

Of course, you cannot overload functions that have "C" linkage, so one
of the functions needs to have C++ linkage. If that proposal is
implemented, then most likely the new function would get C++ linkage.

> You do effectively have both forms, though.  If you
> don't want to use the second parameter, pass it
> a value of 'NULL'.

You are completely missing the point. This library function gives you
a non-const pointer into a const string; that should not happen.

> >  *x = 'A';
>
> This statement replaces the character pointed to by
> 'x'  with the character 'A'.  You've intentionally
> circumvented the 'constness' of the characters pointed
> to by 'line'.

Not intentionally. There is no explicit const_cast in this program,
yet you still managed to cast away constness.

> The language can protect you from mistakes, but
> not deliberate 'malice'.

It could protect from this specific mistake, if it wouldn't have this
defect.

Regards,
Martin

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Wed, 20 Feb 2002 16:38:32 GMT
Raw View
Mike Wahler wrote:
>
> Pete Becker <petebecker@acm.org> wrote in message
> news:3C72F427.29A9E875@acm.org...
> > Mike Wahler wrote:
> > >
> > > > void overwrite(const char* line)
> > > > {
> > > >  char* x;
> > > >  strtod(line, &x);
> > > >  *x = 'A';
> > >
> > > In addition to my other remarks, note that this
> > > statement produces 'undefined behavior.'  (By
> > > attempting to modify const storage.)
> >
> > That's the point: strtod converted a const char* into a char*.
>
> So is this a constraint violation or not?
> I understand it to be merely 'undefined behavior'.
> Can you confirm this?

The code stores through a pointer to const without a const_cast. That's
a coding error. Whether it's undefined depends on what was passed. But
that's not relevant; the request was for a change in interface to make
this mistake harder to make, just as we did with memchr, etc.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Mike Wahler" <mkwahler@ix.netcom.com>
Date: Wed, 20 Feb 2002 22:09:12 GMT
Raw View
Pete Becker <petebecker@acm.org> wrote in message
news:3C73D078.F2A05589@acm.org...
> Mike Wahler wrote:
> >
> > Pete Becker <petebecker@acm.org> wrote in message
> > news:3C72F427.29A9E875@acm.org...
> > > Mike Wahler wrote:
> > > >
> > > > > void overwrite(const char* line)
> > > > > {
> > > > >  char* x;
> > > > >  strtod(line, &x);
> > > > >  *x = 'A';
> > > >
> > > > In addition to my other remarks, note that this
> > > > statement produces 'undefined behavior.'  (By
> > > > attempting to modify const storage.)
> > >
> > > That's the point: strtod converted a const char* into a char*.
> >
> > So is this a constraint violation or not?
> > I understand it to be merely 'undefined behavior'.
> > Can you confirm this?
>
> The code stores through a pointer to const without a const_cast. That's
> a coding error. Whether it's undefined depends on what was passed. But
> that's not relevant; the request was for a change in interface to make
> this mistake harder to make, just as we did with memchr, etc.

OK.  But what I was trying to determine was whether my
assesment of OP's code was accurate, i.e. is the compiler
wrong, or did OP just write UB code?  (I called it the latter)


What I'm calling UB is this (which imo is essentially what OP did):

const char array[] = "ABC";
char *p = array;
*p = 'X';

-Mike



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Ron Natalie <ron@sensor.com>
Date: Wed, 20 Feb 2002 22:11:53 GMT
Raw View

Mike Wahler wrote:
>
> The C library functions are not overloaded.
> They're *C* functions, not C++ functions.

There is precedence for providing additional overloads of C funtions.
There are a bunch in cmath, and also things like memchr.
>

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Wed, 20 Feb 2002 22:34:15 GMT
Raw View
Pete Becker wrote:
>
> Mike Wahler wrote:
> >
> > Pete Becker <petebecker@acm.org> wrote in message
> > news:3C72F427.29A9E875@acm.org...
> > > Mike Wahler wrote:
> > > >
> > > > > void overwrite(const char* line)
> > > > > {
> > > > >  char* x;
> > > > >  strtod(line, &x);
> > > > >  *x = 'A';
> > > >
> > > > In addition to my other remarks, note that this
> > > > statement produces 'undefined behavior.'  (By
> > > > attempting to modify const storage.)
> > >
> > > That's the point: strtod converted a const char* into a char*.
> >
> > So is this a constraint violation or not?
> > I understand it to be merely 'undefined behavior'.
> > Can you confirm this?
>
> The code stores through a pointer to const without a const_cast. That's
> a coding error. Whether it's undefined depends on what was passed.

That is, with or without a const_cast, whether it's undefined depends on
what was passed. It's okay to remove const (with const_cast or through a
C function like strtod) if the data pointed to is not in fact const.

char data[] = "1.0abcdef";
overwrite(data); // okay

const char data[] = "1.0abcdef";
overwrite(data); // not okay

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Wed, 20 Feb 2002 22:39:27 GMT
Raw View
Mike Wahler wrote:
>
> OK.  But what I was trying to determine was whether my
> assesment of OP's code was accurate, i.e. is the compiler
> wrong, or did OP just write UB code?  (I called it the latter)

I thought I posted a followup to my message, but I don't see it, and it
looks like you didn't, either. <g>

>
> What I'm calling UB is this (which imo is essentially what OP did):
>
> const char array[] = "ABC";
> char *p = array;
> *p = 'X';
>

That's a bit different from what the original code did: the assignment
to 'p' is illegal. If you add a cast the behavior becomes undefined. The
compiler could put array in writable memory, or it could put it in
read-only memory.

The original program does essentially the same thing, but without a cast
and non-locally (i.e. you can't tell from looking at the function
overwrite whether the function will succeed, since that depends on
whether the char array that is passed to it is writable).

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 20 Feb 2002 23:42:01 GMT
Raw View
Mike Wahler wrote:
>
> Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote in message
> news:DK8c8.16574$8F6.698472@twister2.libero.it...
> > This looks like both a std and lang issue.
> > All the usual strtoX functions are (more or less) like this:
> >
> >
> > X strtoX( const char* , char** )
> >
> > where X is double, int and so on and the char**  gets the position which
> > stopped the scan.
....
> > imho this a minor error: since obviously this char** point to somewhere
> > inside the other argument,
>
> No, it does not.  Why do you think this is 'obvious?'

His wording was clumsy; what he means is that the pointer pointed at by
the second argument will end up pointing into the same block of memory
that the first argument points at. Which is precisely what you said in
the sections I've clipped, so you're both in agreement on that.

....
> >there should be TWO functions
> >
> > X strtoX( const char* , const char** )
> > X strtoX( char* , char** )
>
> The C library functions are not overloaded.
> They're *C* functions, not C++ functions.

In the C++ standard library, there is a C subset, and there is precedent
for having the C++ version of that subset re-written to make use of
overloading. Take a look at the specifications for strchr(), strpbrk(),
strrchr(), memchr(), and their wide-character counterparts, in section
21.4. Each of them has been re-defined to be overloaded in precisely the
same fashion as is being suggested for strtod(), for precisely the same
reason.

....
> The language can protect you from mistakes, but
> not deliberate 'malice'.

But this is code that could result from a mistake; not in a case this
simple, obviously, but in more complicated cases that depend upon the
same mechanism. I prefer that the language be written to make this
mistake produce a diagnostic. The suggested change to the function's
signature would seem to have that effect, at no particular cost that I
can see.

---
[ 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.research.att.com/~austern/csc/faq.html                ]