appro> > Why pass a reference?  C has been able to pass&return aggregate types since
appro> > v7 :)
appro> Because *that* would *definitely* have impact on *a lot* of things. Pass
appro> by value is an option only if you reimplement all function dealing with
appro> whitened parameter to callback functions. I mean if you want to stick to
appro> void *, then pass by reference is the only (ANSI compliant) option.

Let me see if I got it all.  So far, I've seen the following
alternatives:

  1. ignore the problem (obviously not the right thing to do :-)).
  2. take the parameter in question as we do today, but use a union so
     the compiler will shut up (which is a fancy way of ignoring the
     problem).
  3. whenever the passed parameter is a function pointer, use double
     indirection and assume the caller has really passed a reference
     to a function pointer.
  4. Have the caller tuck the parameter in a union that will represent
     function pointers as well as other pointers, and pass that union
     by value.
  5. Have the caller tuck the parameter in a union that will represent
     function pointers as well as other pointers, and pass that union
     by reference.

Actually, 4 and 5 are basically the same.

Choices 1 and 2 are really just as bad, they're designed to ignore the
problem instead of dealing with it.

Choice 3 assumes that the parameter ni question will be prototyped
and used like this:

        int foo (..., void *parg, ...)
        {
                /* ... */
                int (*fptr)() = *(int (**)())parg;
                /* ... */
        }

It's a good way to deal with the problem in what could be perceived as
a safe way, but for a detail: there's no way to see from the API that
function pointers need to be handled differently than other pointers
when passed down to the functino using them ("doall" and "ctrl"
functions...), and the compiler will not give a hint.

Choices 4 and 5 assumes that the parameter in question will be
prototyped and used like this:

        int foo(..., union fn_n_data parg, ...)
        {
                /* ... */
                int (*fptr)() = (int (*)())(parg.fn);
                /* ... */
        }

(yeah, I know, choice adds a level of indirection)

It's a good way to make it plainly visible to the user of that
function that he/she will have to do something special with that
parameter to get it accepted.


Have I understood it all right?


I dunno about you, but I really don't like choice 3.  At all.  My gut
feeling is that it's way error prone, and may be quite hard to debug.
As I see it, the only real way to make it type safe, ANSI compliant
and avoid error proneness is to stick with choices 4 or 5.  Of course,
that demands a little bit more work, and there's the risk of breaking
a number of programs out there, but as someone (Stephen?) said, there
are already a number of changes since 0.9.4 that may already break a
number of programs.

And yes, there will be the problem of binary compatibility in all
choices but 1 and 2...

-- 
Richard Levitte   \ Spannvägen 38, II \ [EMAIL PROTECTED]
Redakteur@Stacken  \ S-161 43  BROMMA  \ T: +46-8-26 52 47
                    \      SWEDEN       \ or +46-708-26 53 44
Procurator Odiosus Ex Infernis             -- [EMAIL PROTECTED]

Unsolicited commercial email is subject to an archival fee of $400.
See <http://www.stacken.kth.se/~levitte/mail/> for more info.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to