According to http://www.cplusplus.com/reference/cstdlib/strtol/ this function has a signature of long int strtol (const char* str, char** endptr, int base)
.
I wonder, though: If it gets passed a const char *
to the beginning of the string, how does it manage to turn that into a non-const pointer to the first unprocessed character without cheating? What would an implementation of strtol look like that doesn't perform a const_cast?
In the C Programming Language, the strtol function converts a string to a long integer. The strtol function skips all white-space characters at the beginning of the string, converts the subsequent characters as part of the number, and then stops when it encounters the first character that isn't a number.
C Programming/stdlib. h/strtol strtol is a function in the C programming language that converts a string into a long integer. strtol stands for string to long. It is included in the C standard library header file stdlib.
The strtol() function returns the result of the conversion, unless the value would underflow or overflow. If an underflow occurs, strtol() returns LONG_MIN. If an overflow occurs, strtol() returns LONG_MAX. In both cases, errno is set to ERANGE.
endptr − This is the reference to an object of type char*, whose value is set by the function to the next character in str after the numerical value. base − This is the base, which must be between 2 and 36 inclusive, or be the special value 0.
How do you implement
strtol
under const-correctness?
You don't, because strtol
's definition is inherently not const
-correct.
This is a flaw in the C standard library.
There are several standard functions that take a const char*
argument (expected to point the beginning of a character array) and give back a non-const
char*
pointer that can be used to modify that array.
strchr
is one example:
char *strchr(const char *s, int c);
For example:
#include <string.h>
int main(void) {
const char *s = "hello";
char *ptr = strchr(s, 'h');
*ptr = 'H';
}
This program has undefined behavior. On my system, it dies with a segmentation fault.
The problem doesn't occur in strchr
itself. It promises not to modify the string you pass to it, and it doesn't. But it returns a pointer that the caller can then use to modify it.
The ANSI C committee, back in the late 1980s, could have split each such function into two versions, one that acts on const
character arrays and another for non-const
arrays:
char *strchr(char *s, int c);
const char *strcchr(const char *s, int c);
But that would have broken existing pre-ANSI code, written before const
existed. This is the same reason C has not made string literals const
.
C++, which inherits most of C's standard library, deals with this by providing overloaded versions of some functions.
The bottom line is that you, as a C programmer, are responsible for not modifying objects you've defined as const
. In most cases, the language helps you enforce this, but not always.
As for how these functions manage to return a non-const
pointer to const
data, they probably just use a cast internally (not a const_cast
, which exists only in C++). That's assuming they're implemented in C, which is likely but not required.
Most likely it just uses casting.
There are numerious functions that have this same property in standard library. Sacrifiying type safety over simplicity is likely reason, since you cannot overload functions as in C++.
They expect that programmer takes responsibility, and doesn't edit endptr
if str
is, for example, a string literal.
With it's limited type system, C is practical language for practical people.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With