Re: strtol const-ness problem
Greg Herlihy wrote:
dstevel wrote:
The signature for strtol is:
strtol( const char*, char**, int)
[snip]
void func( const char* a )
{
char* tmp;
int i = strtol( a, &tmp, 10 ); // OK
a = tmp;
}
This indirectly allows us to modify the original const char* a through
the new pointer tmp since tmp will point into the character array a. It
doesn't involve a hard cast, but it seems just as dangerous or even
more so because it's not obvious what just happened. The calling
function could see a change in the string pointed to by a, even though
it's passed as pointer to const.
The called function can still use a const_cast to change the value
referenced by the const pointer. So about the only variables that a
program can treat as unmodifiable are those defined as const.
Can someone help me figure out why this is OK?
First it would be rather unusual (not to mention inefficient) for a
program to spend its cycles scanning text for numbers - when the
contents of text being scanned (and by extension, the number values
contained therein) are both constant and were known at compile time.
Therefore, in the vast majority of cases, it is likely that strtol will
be called to process non-const character values.
This is not the only context - it is perfectly reasonable (and *not*
unusual) for a function to have char const * formal parameter and a
const * actual parameter, meaning that the function guarantees not to
modify the (potentially non-const) string, and for this function then
to pass the pointer to strtol. IMHO the signature is not const-correct
- see below.
Second, most C++ programmers are accustomed to be able to pass a
pointer to non-const (such as char *) whenever a function declares a
pointer to const parameter. So, by extension, it is likely that C++
programmers would expect to be able to pass a pointer to a pointer to
non const whenever a pointer to a pointer to const parameter is
declared (in other words to pass char** for a a const char**
parameter).
The more often C/C++ programmers get disabused of this
misconception/expectation, the faster they'll learn correct usage. No
point in supporting incorrect usage simply because the correct usage is
counterintuitive to the less experienced.
[snip]
Finally, since a cast will be necessary either in one case or the other
- it seems that a decision favoring the less unusual cast in the less
likely scenario is, on the whole, nothing other than a decision to
annoy fewer C++ programmers, the fewer number of times.
Greg
On the contrary, the existing signature can be used without casts for
all uses, though safety is sacrificed:
void func( const char* a )
{
char* tmp;
int i = strtol( a, &tmp, 10 );
const char* b = tmp; // any other use of tmp is unsafe, b is
safe (no cast).
}
A const-correct library would have had the signature:
long strtol (const char *nptr, const char **endptr, int base);
However, given that a function may wish to scan and then modify data
from the point scanned to (I expect this use to be far less common),
the following additional signature would have been appropriate:
long strtol (char *nptr, char **endptr, int base);
In C++, two signatures would have been fine. Given that the signature
is in <stdlib.h>, the linkage is extern"C", an overloaded signature is
precluded. I surmise that the provided signature is a compromise,
supporting both uses, but relying on the programmer not to do
"something silly" with the returned pointer.
A bit of a diversion:
Given the const-incorrectness of the signature, I would have advocated
the following single const-correct signature for supporting all
const-correct cases (though it is presumably too late to propose this):
long strtol_new (const char *nptr, int *scannedchars, int base);
With this, the constness is exact (i.e. the compiler will permit all
safe and no unsafe combinations of uncommenting the "const"):
char /*const*/ * a = "1234abcd";
int i;
long value = strtol_new(a,&i,10);
char /*const*/ * p = a+i; // the original endptr parameter
Manfred
---
[ 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.comeaucomputing.com/csc/faq.html ]