From 5387284604766136264
X-Google-Thread: f78e5,1d1109cd86668825
X-Google-Attributes: gidf78e5,public
X-Google-Language: ENGLISH,ASCII-7-bit
Path: g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local02.nntp.dca.giganews.com!nntp.speakeasy.net!news.speakeasy.net.POSTED!not-for-mail
NNTP-Posting-Date: Wed, 16 Aug 2006 11:30:02 -0500
Return-Path: <devnull@stump.algebra.com>
X-Authentication-Warning: mulga.csse.unimelb.edu.au: fjh set sender to devnull@stump.algebra.com using -f
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
X-Original-To: std-c++@mailman.ucar.edu
Delivered-To: std-c++@mailman.ucar.edu
From: "Kristof Zelechovski" <giecrilj@stegny.2a.pl>
Newsgroups: comp.std.c++
Subject: Re: strtol const-ness problem
Organization: Internet Partners
Message-ID: <ebvcg6$2phu$1@news2.ipartners.pl>
References: <1155392893.026182.121030@h48g2000cwc.googlegroups.com>   <1155445528.956928.185450@p79g2000cwp.googlegroups.com> <1155587670.517846.8770@h48g2000cwc.googlegroups.com>
X-Complaints-To: abuse@ipartners.pl
X-RFC2646: Format=Flowed; Original
X-Newsreader: Microsoft Outlook Express 6.00.2900.2869
X-MSMail-Priority: Normal
X-Priority: 3
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2962
X-Virus-Scanned: amavisd-new at ucar.edu
X-Virus-Scanned: amavisd-new at csse.unimelb.edu.au
Approved: Fergus Henderson <fjh@cs.mu.oz.au>, moderator of comp.std.c++
X-Virus-Scanned: amavisd-new at csse.unimelb.edu.au
Date: Wed, 16 Aug 2006 11:28:50 CST
Lines: 118
NNTP-Posting-Host: 65.182.171.162
X-Trace: sv3-0MHIsbH3xda18+SHhXtvEsHkW6ESQCQh7pQTCOevucuQjhzA2f2jzcBQ4zib7Fv6hiW3th0xVsLGPPf!fKVIW/qsXj0o25NvtexhiSe6nrIltkiGwxE58Zj4iPa6lUVdeuiCW9SxLAX8GD9/XbvN4i1Xrx+K!wSsA3Mto/QnLr+s=
X-Complaints-To: abuse@speakeasy.net
X-DMCA-Complaints-To: abuse@speakeasy.net
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.32
Xref: g2news2.google.com comp.std.c++:3293


Uzytkownik "Manfred von Willich" <manfred@techniroot.co.za> napisal w 
wiadomosci news:1155587670.517846.8770@h48g2000cwc.googlegroups.com...
>
> 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.
>

Suppose you have extern "C" strtol(char const [], char const **, int).  How 
do you make a non-const overload?

A: First, we should use a reference instead of a pointer.
static inline long strtol(char const buf[], char const *&end, int base) { 
return strtol(buf, &end, base); }
Next, observe that we can do pointer arithmetic on pointers belonging to the 
same buffer:
static inline long strtol(char buf[], char *&end, int base) {
auto char const *gotyou; auto long result(strtol(buf, gotyou, base)); end = 
gotyou - buf + buf; return result; }
Ready.
Chris 



---
[ 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                      ]



