Topic: strtol and const-safety
Author: daniel.kruegler@googlemail.com
Date: Mon, 4 May 2009 18:55:08 CST Raw View
On 3 Mai, 18:20, Marc <marc.gli...@gmail.com> wrote:
> Hello,
>
> I notice that strtol keeps the same declaration in C++ as in C.
>
> long int strtol(const char *nptr, char **endptr, int base);
>
> This means that this function can be used as a const_cast.
>
> const char* text;
> char* hack;
> strtol(line,&hack,0);
>
> In a similar situation, the prototypes of strstr and similar functions
> were modified to provide const and non-const overloads. Is there a
> reason not to do the same for strtol?
Not that I know of, except backward compatibility ;-)
> long int strtol(const char *nptr, const char **endptr, int base);
> long int strtol(char *nptr, char **endptr, int base);
IMO your observation is correct. It seems that the C++ standard
did only add proper overloads in those cases where the function
type and a function parameter (both pointer types) are const-
involved.
They did not so (IMO incorrectly) for the equivalent situation where
a function parameter of pointer type and another function parameter
of pointer to pointer type are const involved. So your mentioned
problem would cover several of functions, I think it concerns all
strto*
(but not strtok) and all wcsto* (but not wcstok) functions.
Greetings from Bremen,
Daniel Kr gler
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Marc <marc.glisse@gmail.com>
Date: Mon, 4 May 2009 18:54:11 CST Raw View
On May 3, 1:28 pm, Steve Clamage <stephen.clam...@sun.com> wrote:
> On Sun, 3 May 2009 10:20:59 CST, Marc <marc.gli...@gmail.com> wrote:
> >I notice that strtol keeps the same declaration in C++ as in C.
>
> >long int strtol(const char *nptr, char **endptr, int base);
>
> >In a similar situation, the prototypes of strstr and similar functions
> >were modified to provide const and non-const overloads. Is there a
> >reason not to do the same for strtol?
>
> Consider the standard C function
> char* strchr(const char*, int);
> You could write
> void foo(const char* src)
> {
> char* q = strchr(src, 'a');
> if( q )
> *q = b; // oops}
>
> There is nothing here for the compiler even to warn about. But if you
> pass an actual const string to foo, the program has undefined, and
> probably undesirable, behavior. On some platforms, the program will
> crash on the attempted assignment.
[...]
> strtol, on the other hand, is already type-safe. There is no need to
> add a version that takes a non-const nptr, since the addition would
> not allow you to write any programs that you cannot already safely
> write.
void foo(const char* src)
{
char* q;
strtol(src,&q,0);
if( q )
*q = 'b'; // oops
}
The situation looks pretty similar to me...
But I believe I know the reason.
For strstr, the const-correct versions work with the C prototype as
well as the C++ ones:
const char* a; char* b;
const char* c=strstr(a,...); char*d=strstr(b,...);
On the other hand, for strtol, with the C prototype, the following
fails (with an error in C++, but just a warning in C it seems for the
compilers I tried):
const char* a;
const char* b;
strtol(a,&b,0);
You actually need to use the ugly "char*b;" without "const" to make it
work. Now my guess it that we want code written for the C prototype to
still work in C++ (ie precisely the const-incorrect version I wanted
to forbid...). However, I really think the const-correct version
should also be allowed (after all, it even seems to work in C, despite
a warning), so strtol should have the 2 prototypes:
long int strtol(const char *nptr, const char **endptr, int base);
long int strtol(const char *nptr, char **endptr, int base);
(notice the extra const in the second prototype compared to my first
message, so it matches the C prototype)
This still allows the const-incorrect version, for compatibility, but
at least it allows the const-correct one...
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: daniel.kruegler@googlemail.com
Date: Mon, 4 May 2009 18:53:16 CST Raw View
On 3 Mai, 22:28, Steve Clamage <stephen.clam...@sun.com> wrote:
> On Sun, 3 May 2009 10:20:59 CST, Marc <marc.gli...@gmail.com> wrote:
> >Hello,
>
> >I notice that strtol keeps the same declaration in C++ as in C.
>
> >long int strtol(const char *nptr, char **endptr, int base);
>
> >In a similar situation, the prototypes of strstr and similar functions
> >were modified to provide const and non-const overloads. Is there a
> >reason not to do the same for strtol?
>
> Consider the standard C function
> char* strchr(const char*, int);
> You could write
> void foo(const char* src)
> {
> char* q = strchr(src, 'a');
> if( q )
> *q = b; // oops}
>
> There is nothing here for the compiler even to warn about. But if you
> pass an actual const string to foo, the program has undefined, and
> probably undesirable, behavior. On some platforms, the program will
> crash on the attempted assignment.
>
> C++ adds a pair of replacement strchr functions, one taking and
> returning a const char* and the other a non-const char*. The compiler
> will catch any accidental violation of the type system.
>
> strtol, on the other hand, is already type-safe. There is no need to
> add a version that takes a non-const nptr, since the addition would
> not allow you to write any programs that you cannot already safely
> write.
I think the OP had a similar example in his mind like yours:
void foo(const char* src)
{
char* hack = 0;
strtol(src, &hack, 0);
if( hack )
*hack = b; // oops
}
- Daniel
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Pavel Minaev <int19h@gmail.com>
Date: Mon, 4 May 2009 20:18:59 CST Raw View
On May 3, 1:28 pm, Steve Clamage <stephen.clam...@sun.com> wrote:
> Consider the standard C function
> char* strchr(const char*, int);
> You could write
> void foo(const char* src)
> {
> char* q = strchr(src, 'a');
> if( q )
> *q = b; // oops}
>
> There is nothing here for the compiler even to warn about. But if you
> pass an actual const string to foo, the program has undefined, and
> probably undesirable, behavior. On some platforms, the program will
> crash on the attempted assignment.
>
> C++ adds a pair of replacement strchr functions, one taking and
> returning a const char* and the other a non-const char*. The compiler
> will catch any accidental violation of the type system.
>
> strtol, on the other hand, is already type-safe. There is no need to
> add a version that takes a non-const nptr, since the addition would
> not allow you to write any programs that you cannot already safely
> write.
I believe the question wasn't about "nptr", but about "char **endptr"
- that is, why isn't there a "const char **endptr" overload.
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Tue, 5 May 2009 09:46:23 CST Raw View
On May 3, 10:28 pm, Steve Clamage <stephen.clam...@sun.com> wrote:
> On Sun, 3 May 2009 10:20:59 CST, Marc <marc.gli...@gmail.com> wrote:
> >I notice that strtol keeps the same declaration in C++ as in C.
> >long int strtol(const char *nptr, char **endptr, int base);
> >In a similar situation, the prototypes of strstr and similar
> >functions were modified to provide const and non-const
> >overloads. Is there a reason not to do the same for strtol?
> Consider the standard C function
> char* strchr(const char*, int);
> You could write
> void foo(const char* src)
> {
> char* q = strchr(src, 'a');
> if( q )
> *q = b; // oops}
> There is nothing here for the compiler even to warn about. But
> if you pass an actual const string to foo, the program has
> undefined, and probably undesirable, behavior. On some
> platforms, the program will crash on the attempted assignment.
> C++ adds a pair of replacement strchr functions, one taking
> and returning a const char* and the other a non-const char*.
> The compiler will catch any accidental violation of the type
> system.
> strtol, on the other hand, is already type-safe. There is no
> need to add a version that takes a non-const nptr, since the
> addition would not allow you to write any programs that you
> cannot already safely write.
Doesn't strtol suffer from the same problem?
void foo( char const* src )
{
char* q ;
long l = strtol( src, &q, 10 ) ;
if ( q ) {
*q = 'b' ;
}
}
If I call foo( "12xyz" ), foo is going to try to write into the
constant string data, even though it was passed as a char
const*, and there is nothing for the compiler to complain about.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Bart van Ingen Schenau <bart@ingen.ddns.info>
Date: Tue, 5 May 2009 14:14:52 CST Raw View
Steve Clamage wrote:
> On Sun, 3 May 2009 10:20:59 CST, Marc <marc.glisse@gmail.com> wrote:
>
>>Hello,
>>
>>I notice that strtol keeps the same declaration in C++ as in C.
>>
>>long int strtol(const char *nptr, char **endptr, int base);
>>
>>In a similar situation, the prototypes of strstr and similar functions
>>were modified to provide const and non-const overloads. Is there a
>>reason not to do the same for strtol?
>
> Consider the standard C function
> char* strchr(const char*, int);
> You could write
> void foo(const char* src)
> {
> char* q = strchr(src, 'a');
> if( q )
> *q = b; // oops
> }
> There is nothing here for the compiler even to warn about. But if you
> pass an actual const string to foo, the program has undefined, and
> probably undesirable, behavior. On some platforms, the program will
> crash on the attempted assignment.
>
> C++ adds a pair of replacement strchr functions, one taking and
> returning a const char* and the other a non-const char*. The compiler
> will catch any accidental violation of the type system.
>
> strtol, on the other hand, is already type-safe. There is no need to
> add a version that takes a non-const nptr, since the addition would
> not allow you to write any programs that you cannot already safely
> write.
Consider a similar function with strtol:
void bar(const char* src)
{
char* q;
strtol(src, &q, 0);
if( q )
*q = b; // oops
}
With regards to potential UB and detectability by a C compiler, this
function is identical to foo.
I think that the true reason why there are no type-safe overloads for
strtol is because adding them is not straightforward (as for the strchr,
strcpy, etc. functions), because the two parameters have different
levels of indirection. And it would probably have broken too much code
that was supposed to compile in both C and C++.
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Marc <marc.glisse@gmail.com>
Date: Sun, 3 May 2009 10:20:59 CST Raw View
Hello,
I notice that strtol keeps the same declaration in C++ as in C.
long int strtol(const char *nptr, char **endptr, int base);
This means that this function can be used as a const_cast.
const char* text;
char* hack;
strtol(line,&hack,0);
In a similar situation, the prototypes of strstr and similar functions
were modified to provide const and non-const overloads. Is there a
reason not to do the same for strtol?
long int strtol(const char *nptr, const char **endptr, int base);
long int strtol(char *nptr, char **endptr, int base);
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Steve Clamage <stephen.clamage@sun.com>
Date: Sun, 3 May 2009 14:28:49 CST Raw View
On Sun, 3 May 2009 10:20:59 CST, Marc <marc.glisse@gmail.com> wrote:
>Hello,
>
>I notice that strtol keeps the same declaration in C++ as in C.
>
>long int strtol(const char *nptr, char **endptr, int base);
>
>In a similar situation, the prototypes of strstr and similar functions
>were modified to provide const and non-const overloads. Is there a
>reason not to do the same for strtol?
Consider the standard C function
char* strchr(const char*, int);
You could write
void foo(const char* src)
{
char* q = strchr(src, 'a');
if( q )
*q = b; // oops
}
There is nothing here for the compiler even to warn about. But if you
pass an actual const string to foo, the program has undefined, and
probably undesirable, behavior. On some platforms, the program will
crash on the attempted assignment.
C++ adds a pair of replacement strchr functions, one taking and
returning a const char* and the other a non-const char*. The compiler
will catch any accidental violation of the type system.
strtol, on the other hand, is already type-safe. There is no need to
add a version that takes a non-const nptr, since the addition would
not allow you to write any programs that you cannot already safely
write.
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Dennett <james.dennett@gmail.com>
Date: Mon, 4 May 2009 18:56:17 CST Raw View
On May 3, 1:28 pm, Steve Clamage <stephen.clam...@sun.com> wrote:
> On Sun, 3 May 2009 10:20:59 CST, Marc <marc.gli...@gmail.com> wrote:
> >Hello,
>
> >I notice that strtol keeps the same declaration in C++ as in C.
>
> >long int strtol(const char *nptr, char **endptr, int base);
>
> >In a similar situation, the prototypes of strstr and similar functions
> >were modified to provide const and non-const overloads. Is there a
> >reason not to do the same for strtol?
>
> Consider the standard C function
> char* strchr(const char*, int);
> You could write
> void foo(const char* src)
> {
> char* q = strchr(src, 'a');
> if( q )
> *q = b; // oops}
>
> There is nothing here for the compiler even to warn about. But if you
> pass an actual const string to foo, the program has undefined, and
> probably undesirable, behavior. On some platforms, the program will
> crash on the attempted assignment.
>
> C++ adds a pair of replacement strchr functions, one taking and
> returning a const char* and the other a non-const char*. The compiler
> will catch any accidental violation of the type system.
>
> strtol, on the other hand, is already type-safe. There is no need to
> add a version that takes a non-const nptr, since the addition would
> not allow you to write any programs that you cannot already safely
> write.
#include <cstdlib>
#include <cstdio>
#include <cassert>
int main() {
char const *text = "hello";
char* nc = NULL;
std::strtol(text, &nc, 10); // bad: gives out a non-const pointer
assert(nc == text); // bad, nc is non-const, text is const
*nc='t';
std::printf("%s\n", nc);
}
This has undefined behavior, and crashes on my platform: strtol is not
const-correct, and will happily return me a char* pointing at
immutable characters. It's the same problem that was fixed for
strchr, no?
-- James
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]