On Sat, Jun 15, 2002 at 12:14:00PM +0200, Bodo Moeller wrote:

> > Using "const unsigned char **", however, is not 100% api-compatible, because
> > you can't safely pass an "unsigned char **" to it, for complicated reasons
> > explained in the URL I sent earlier.
> 
> [http://www.geocrawler.com/archives/3/362/1997/9/0/2036587/]
> 
> I see, so this is an C++ speciality.  As far as C is concerned, the
> types should be incompatible between any of these three variants, but
> compilers tend not to look that close (and otherwise you'd use a
> cast).  Writing code that tries to change a 'const char' object as
> shown at the above URL is possible -- the actual assignment is
> illegal, but in general the compiler cannot catch this.

I don't understand why you say this is C++-specific: I think C does const in
the same way.

My original suggestion (two consts) is not incompatible with either of the
others, it just promises a level of constness that you're not actually going
to provide.

> > Unfortunately, I don't know a way around it: the problem is that the beta1
> > level of constness looks right, but doesn't _actually_ promise the constness
> > that it looks like it does, due to the crazy hackery described in the URL I
> > sent earlier.
> 
> Prototypes alone don't really guarantee constness anyway.  If a
> function is passed a 'const int *' pointer and knows somehow that the
> object pointed to is not 'const' (i.e. the pointer was 'int *'
> originally), it may cast the pointer back to 'int *' and modify the
> object.

Prototypes are really just a clue for the user and implementer of a class: a
program would run exactly the same if "const" were globally #defined to be
meaningless.

If you're not concerned about what you promise the user (and a good comment
above the prototype can repair that promise anyway) then use my original
suggestion

        const unsigned char * const *
        
which will happily accept parameters of any of these types:

        unsigned char **
        const unsigned char **
        const unsigned char * const *
        
...and then typecast it _yourself_ inside the function.  This maintains API
compatibility and lets you pass "const unsigned char **" objects, which is
what you presumably wanted.

> >                It also makes the API incompatible with older versions.  I
> > can't pass the address of "unsigned char *p" to the new function.
> 
> I guess you'll have to include a cast to the new type depending on the
> value of OPENSSL_VERSION_NUMBER.  I know this is ugly, but I don't
> think we should un-constify the prototype to avoid such problems.

Oh, argh, no!  Please, please don't do this.  So far we've managed to
avoid all such things and wvstreams goes back to quite old revs of openssl.

What's the point of an api "cleanup" that makes user code uglier?

> (In fact we'll have to make various other prototype changes to clean
> up the API, for example 'int' quite often should be 'size_t' etc.)

This might produce warnings, but never errors, I think.

Have fun,

Avery
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to