Topic: strtod and const


Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1999/08/16
Raw View
[This originally arose on comp.std.c; I am cross-posting to comp.std.c++.]

[Moderator note: there is no followup-to. Please follow-up
 to the right group (depending on the subject of your
 article). --vb]

Martin Ambuhl <mambuhl@earthlink.net> writes:

>Bjorn Reese wrote:
>>
>> While I was building a wrapper for string functions I noticed that
>> the prototype for strtod() appears to be wrong. It is defined as
>>
>>   double int strtod(const char *, char **);
>>
>> The first argument points to a string to be converted, and the second
>> argument (if non-NULL) is used to return the location of the last
>> character used in the convertion.
>>
>> The first argument tells that the string consists of const chars,
>> but the second does not. Shouldn't the second argument be 'const
>> char **'?
>>
>> The same applies to strtof().
>
>When in
>   strtod(nptr, endptr);
>"If the subject sequence is empter or does not have the expected form
>... the value of nptr is stored in the object pointed to by endptr,
>provided endptr is not a null pointer."  So the second argument cannot
>be const char**.

That shows why the second argument can't have type `char *const *'.
But it doesn't show why the second argument can't have type `const char **'.

I presume the reason for making the second argument of strtod()
`char **' rather than `const char **' is similar to the reason for
making strchr() return `char *' rather than `const char *': it avoids
the need for a cast in caller in the case when the first argument passed
in is actually of type `char *' rather than `const char *'.

Really it ought to be something like

 template <constness Const>
 double int strtod(Const char *, Const char **);

but C doesn't provide any way of doing that.

C++ doesn't support that either, but in C++ you can do similar things using
overloading.  The C++ standard library replaces the single strchr() function
in the C standard library

 char *strchr(const char *, int);

with two overloaded versions

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

but for some reason it doesn't do anything similar for strtod().
I suppose the problem is that simply replacing strtod() with two overloaded
versions

 double int strtod(char *, char **);
 double int strtod(const char *, const char **);

would break backwards compatibility.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]