Re: Sadistic C compiler...

2000-01-26 Thread Bodo Moeller

On Thu, Jan 20, 2000, Richard Levitte - VMS Whacker wrote:

 babinebell I think we should seperate the functions handling values
 babinebell and the functions handling callbacks:
 babinebell 
 babinebell int BIO_ctrl_callback(BIO *bp,int cmd,long larg,int (*cb)());

 Hmm, actually, I like that alternative.  That allows us to go around
 the whole union/pass-by-value/and-so-on brouhaha...  :-)

Looks ok.  Will you implement it?
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-26 Thread Bodo Moeller

On Wed, Jan 26, 2000, Bodo Moeller wrote:
 On Thu, Jan 20, 2000, Richard Levitte - VMS Whacker wrote:

 Hmm, actually, I like that alternative.  That allows us to go around
 the whole union/pass-by-value/and-so-on brouhaha...  :-)

 Looks ok.  Will you implement it?

Here "you" == Richard, in case it wasn't clear.
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-26 Thread Richard Levitte - VMS Whacker

bodo  babinebell I think we should seperate the functions handling values
bodo  babinebell and the functions handling callbacks:
bodo  babinebell 
bodo  babinebell int BIO_ctrl_callback(BIO *bp,int cmd,long larg,int (*cb)());
bodo 
bodo  Hmm, actually, I like that alternative.  That allows us to go around
bodo  the whole union/pass-by-value/and-so-on brouhaha...  :-)
bodo 
bodo Looks ok.  Will you implement it?

Sure.

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



Re: Sadistic C compiler...

2000-01-23 Thread Andy Polyakov

 It's *not* VMS specific! DEC C 6.2 for Unix issues very similar warning.
But it looks like DEC has VMS specific reason to be nervous about the
matter. Consider the following code:

#pragma required_pointer_size save /* Save the previous pointer size */
#pragma required_pointer_size 64 /* Set pointer size to 64 bits */
typedef void *ptr_64; /* Define a 64-bit char pointer */
typedef void (*func_ptr64) ();
#pragma required_pointer_size restore  /* Restore the pointer size */

main ()
{ printf ("%d%d%d%d\n",sizeof(void(*)()),sizeof(void *),
   sizeof(func_64),sizeof(ptr_64));
}

It prints 4488! I.e. if program is compiled without /POINTER=64
command-line option:-) The worst is that it's possible to have say a
function returning 64-bit pointer in one module declared as function
returning 32-bit pointer in another module and link those modules
together... Well, it might still work as arguments are passed and
results returned through 64-bit register in either case, but the
potential is there. What would definitely break is a pointer to 64-bit
pointer vs. pointer to a 32-bit pointer, huh?

Further references:

http://www.digital.com/info/DTJM05/DTJM05HM.HTM
http://www.digital.com/info/DTJM06/DTJM06HM.HTM

Cheers. Andy.
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-21 Thread Richard Levitte - VMS Whacker

babinebell I think we should seperate the functions handling values
babinebell and the functions handling callbacks:
babinebell 
babinebell int BIO_ctrl_callback(BIO *bp,int cmd,long larg,int (*cb)());
babinebell 
babinebell Is not nice, requires changing of some structures but
babinebell seems to be the best save way...

Hmm, actually, I like that alternative.  That allows us to go around
the whole union/pass-by-value/and-so-on brouhaha...  :-)

-- 
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]
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-20 Thread Bodo Moeller

Richard Levitte - VMS Whacker [EMAIL PROTECTED]:

 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.

No, 5 is to 4 what (for function pointers) 3 is to 1.

 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.

It will give a hint!  Just don't use casts, and the compiler will
complain when you try to pass a function pointer directly.  Simarly,
the function using the function pointer can be written without casts
if it is using the pointer correctly; if it's incorrect, you need
casts to make the warning go away.

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

Choice 4 should be binary compatible as well, because on platforms
where choice 1 and 2 work in practice both types of pointers
have the same length, so probably the union won't be any different.
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-20 Thread Ben Laurie

Richard Levitte - VMS Whacker wrote:
   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.

There's a memory management issue with 5 that 4 cures.

Cheers,

Ben.

--
SECURE HOSTING AT THE BUNKER! http://www.thebunker.net/hosting.htm

http://www.apache-ssl.org/ben.html

"My grandfather once told me that there are two kinds of people: those
who work and those who take the credit. He told me to try to be in the
first group; there was less competition there."
 - Indira Gandhi
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-20 Thread Bodo Moeller

Andy Polyakov [EMAIL PROTECTED]:

   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.

 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);
 /* ... */
 }

 Why assign? parg.fn() (#4) and parg-fn() (#5) suffice and are perfectly
 readable/debuggable, aren't they?

In the above example, yes; but not when it's really

int (*fptr)(int, char) = (int (*)())(parg.fn);

or even

long (*fptr)(int, char) = (int (*)())(parg.fn);


 My vote is #5 for crypto/mem_dbg.c, crypto/bio/bss_conn.c, ssl/s3_lib.c
 with new calls and separate ctl codes for binary compatibility [...]

I don't think it's worth to blow up the code that much to get binary
compatibility (but by adding a couple of lines of these "switch"
statements we can generate error messages that tell everyone to change
their programs -- then, a version or two later, we can get rid of this
extra code).  It's easy to provide source code compatibility except
when SSL_ctrl and the other similar functions are called directly --
to catch these cases we should slightly rename the SSL_ctrl command
codes to cause compiler errors for programs that call it anyway.
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-20 Thread Andy Polyakov

 appro  Why pass a reference?  C has been able to passreturn 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.
Absolutely yes.
 
 Actually, 4 and 5 are basically the same.
Well, it's actually 3 and 5 which are the same. I.e. in the sense that
equivalent machine code is generated in both cases. In case #3 you do
*((**))p() and in case #5 - (union *)p-func(). The advantage of the #5
over the #3 is that it's more error prone (as *you* have pointed out
yourself:-).
 
 Choices 1 and 2 are really just as bad, they're designed to ignore the
 problem instead of dealing with it.
Yes.
 
 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.
Well, you probably don't have to tell the difference at the *published*
"API" level (API is in quotes as there's a lot of macros). We have
crypto/mem_dbg.c, crypto/bio/bss_conn.c, ssl/s3_lib.c and
crypto/objects/o_names.c offending the compiler. First is no problem at
all (i.e. either #3 or #5) and it even remains binary compatible. Second
and third can be fixed by promoting some macros to calls (which is a
"good thing(tm)") and ensure *source* code compatibility and can be done
with minimal changes (again provided that #3 or #4 are chosen). It's
even possible to provide binary compatibility in first three by
introducing separate ctl codes dealing with unions pass by value and
pass by reference. Pass by value can be guarded with
"if(sizeof(void(*)())!=sizeof(void*))abort();" ensuring intended
behavior. I keep my mouth shut about o_names.c for this time as I
haven't got the whole picture after 5 mins staring at it (but I'll get
there eventually:-).
 
 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);
 /* ... */
 }
Why assign? parg.fn() (#4) and parg-fn() (#5) suffice and are perfectly
readable/debuggable, aren't they?
 
 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.
My vote is #5 for crypto/mem_dbg.c, crypto/bio/bss_conn.c, ssl/s3_lib.c
with new calls and separate ctl codes for binary compatibility (I can
fix up bss_conn.c and s3_lib.c to *show* what I mean). I'll be back
about o_names.c...
 
 And yes, there will be the problem of binary compatibility in all
 choices but 1 and 2...
*and* #4 on the supported platforms. I mean on all *currently* supported
platforms sizeof(void(*)()) == sizeof(void *) and pass of union (by
value) is *equivalent* to pass of pointer (by value).

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



Re: Sadistic C compiler...

2000-01-20 Thread Andy Polyakov

 appro My vote is #5 for crypto/mem_dbg.c, crypto/bio/bss_conn.c,
 appro ssl/s3_lib.c with new calls and separate ctl codes for binary
 appro compatibility (I can fix up bss_conn.c and s3_lib.c to *show*
 appro what I mean). I'll be back about o_names.c...
Below is what I ment for bss_conn.c. It's both source and binary
compatible and those are the *only* changes required. If everybody
agrees on it, I'll fix-up s3_lib.c in same way directly in cvs tree
(throwing some extra comments around and "promoting" even
*_get_info_callback to call for consistency:-) Cheers. Andy.

*** ./bio.h.origMon Sep 27 16:00:09 1999
--- ./bio.h Thu Jan 20 16:57:00 2000
***
*** 116,121 
--- 116,122 
  /* callback is int cb(BIO *bio,state,ret); */
  #define BIO_CTRL_SET_CALLBACK 14  /* opt - set callback function */
  #define BIO_CTRL_GET_CALLBACK 15  /* opt - set callback function */
+ #define BIO_CTRL_ANSI_SET_CALLBACK16  /* opt - set callback function */
  
  #define BIO_CTRL_SET_FILENAME 30  /* BIO_s_file special */
  
***
*** 456,462 
--- 457,467 
  size_t BIO_ctrl_wpending(BIO *b);
  #define BIO_flush(b)  (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
  #define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0,(char 
*)cbp)
+ #if 0
  #define BIO_set_info_callback(b,cb) (int)BIO_ctrl(b,BIO_CTRL_SET_CALLBACK,0,(char 
*)cb)
+ #else
+ int BIO_set_info_callback (BIO *b, int (*cb)());
+ #endif
  
  /* For the BIO_f_buffer() type */
  #define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
*** ./bss_conn.c.orig   Thu Jun 10 19:00:10 1999
--- ./bss_conn.cThu Jan 20 16:54:36 2000
***
*** 447,452 
--- 447,454 
return(ret);
}
  
+ typedef union { int (*func) (); void *ptr; } sin_of_ansification;
+ 
  static long conn_ctrl(BIO *b, int cmd, long num, char *ptr)
{
BIO *dbio;
***
*** 573,579 
(void)BIO_set_info_callback(dbio,data-info_callback);
break;
case BIO_CTRL_SET_CALLBACK:
!   data-info_callback=(int (*)())ptr;
break;
case BIO_CTRL_GET_CALLBACK:
{
--- 575,587 
(void)BIO_set_info_callback(dbio,data-info_callback);
break;
case BIO_CTRL_SET_CALLBACK:
!   if (sizeof(void (*)()) == sizeof(void *))
!   {
!   sin_of_ansification sin;
!   sin.ptr = ptr;
!   data-info_callback=sin.func;
!   }
!   elseabort ();
break;
case BIO_CTRL_GET_CALLBACK:
{
***
*** 583,588 
--- 591,599 
*fptr=data-info_callback;
}
break;
+   case BIO_CTRL_ANSI_SET_CALLBACK:
+   data-info_callback=((sin_of_ansification *)ptr)-func;
+   break;
default:
ret=0;
break;
***
*** 614,618 
--- 625,636 
}
}
  
+ int BIO_set_info_callback (BIO *b, int (*cb)())
+   {
+   sin_of_ansification not_a_sin;
+ 
+   not_a_sin.func = cb;
+   return BIO_ctrl (b,BIO_CTRL_ANSI_SET_CALLBACK,0,(void *)not_a_sin);
+   }
  #endif
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-20 Thread Richard Levitte - VMS Whacker

appro Well, it's actually 3 and 5 which are the same. I.e. in the

Ah, right, I made the comparison from a language semantics point of
view...

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

appro Well, you probably don't have to tell the difference at the
appro *published* "API" level (API is in quotes as there's a lot of
appro macros).

Uhmm...  Why not?

appro Why assign? parg.fn() (#4) and parg-fn() (#5) suffice and are perfectly
appro readable/debuggable, aren't they?

Yes.  Consider the above an example, nothing else.  The real thing
would probably be to assign a callback variable...

appro  I dunno about you, but I really don't like choice 3.  At all.  My gut
appro  feeling is that it's way error prone, and may be quite hard to debug.
appro  As I see it, the only real way to make it type safe, ANSI compliant
appro  and avoid error proneness is to stick with choices 4 or 5.

appro My vote is #5 for crypto/mem_dbg.c, crypto/bio/bss_conn.c,
appro ssl/s3_lib.c with new calls and separate ctl codes for binary
appro compatibility (I can fix up bss_conn.c and s3_lib.c to *show*
appro what I mean). I'll be back about o_names.c...

Why have it different for o_names.c?

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

appro *and* #4 on the supported platforms. I mean on all *currently*
appro supported platforms sizeof(void(*)()) == sizeof(void *) and
appro pass of union (by value) is *equivalent* to pass of pointer (by
appro value).

Quite right.

Sounds like the ultimate way of choice would be #4...

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



Re: Sadistic C compiler...

2000-01-20 Thread Richard Levitte - VMS Whacker

appro *** ./bio.h.origMon Sep 27 16:00:09 1999
appro --- ./bio.h Thu Jan 20 16:57:00 2000
appro ***
appro *** 116,121 
appro --- 116,122 
appro   /* callback is int cb(BIO *bio,state,ret); */
appro   #define BIO_CTRL_SET_CALLBACK 14  /* opt - set callback function */
appro   #define BIO_CTRL_GET_CALLBACK 15  /* opt - set callback function */
appro + #define BIO_CTRL_ANSI_SET_CALLBACK16  /* opt - set callback function */
appro   
appro   #define BIO_CTRL_SET_FILENAME 30  /* BIO_s_file special */
appro   
appro ***
appro *** 456,462 
appro --- 457,467 
appro   size_t BIO_ctrl_wpending(BIO *b);
appro   #define BIO_flush(b)  (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
appro   #define BIO_get_info_callback(b,cbp) 
(int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0,(char *)cbp)
appro + #if 0
appro   #define BIO_set_info_callback(b,cb) 
(int)BIO_ctrl(b,BIO_CTRL_SET_CALLBACK,0,(char *)cb)
appro + #else
appro + int BIO_set_info_callback (BIO *b, int (*cb)());
appro + #endif
appro   
appro   /* For the BIO_f_buffer() type */
appro   #define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
appro *** ./bss_conn.c.orig   Thu Jun 10 19:00:10 1999
appro --- ./bss_conn.cThu Jan 20 16:54:36 2000
appro ***
appro *** 447,452 
appro --- 447,454 
appro return(ret);
appro }
appro   
appro + typedef union { int (*func) (); void *ptr; } sin_of_ansification;
appro + 
appro   static long conn_ctrl(BIO *b, int cmd, long num, char *ptr)
appro {
appro BIO *dbio;
appro ***
appro *** 573,579 
appro (void)BIO_set_info_callback(dbio,data-info_callback);
appro break;
appro case BIO_CTRL_SET_CALLBACK:
appro !   data-info_callback=(int (*)())ptr;
appro break;
appro case BIO_CTRL_GET_CALLBACK:
appro {
appro --- 575,587 
appro (void)BIO_set_info_callback(dbio,data-info_callback);
appro break;
appro case BIO_CTRL_SET_CALLBACK:
appro !   if (sizeof(void (*)()) == sizeof(void *))
appro !   {
appro !   sin_of_ansification sin;
appro !   sin.ptr = ptr;
appro !   data-info_callback=sin.func;
appro !   }
appro !   elseabort ();
appro break;
appro case BIO_CTRL_GET_CALLBACK:
appro {
appro ***
appro *** 583,588 
appro --- 591,599 
appro *fptr=data-info_callback;
appro }
appro break;
appro +   case BIO_CTRL_ANSI_SET_CALLBACK:
appro +   data-info_callback=((sin_of_ansification *)ptr)-func;
appro +   break;
appro default:
appro ret=0;
appro break;
appro ***
appro *** 614,618 
appro --- 625,636 
appro }
appro }
appro   
appro + int BIO_set_info_callback (BIO *b, int (*cb)())
appro +   {
appro +   sin_of_ansification not_a_sin;
appro + 
appro +   not_a_sin.func = cb;
appro +   return BIO_ctrl (b,BIO_CTRL_ANSI_SET_CALLBACK,0,(void *)not_a_sin);
appro +   }
appro   #endif

Hmm.  That's basically an anonymous choice 4 and 5 (depending on ctl
code).  My thought about that one was that BIO_ctrl would be declared
and defined to take a 'sin_of_ansification *' as argument instead of a
'void *' (a non-anonymous variant 4).  This would still be binary
compatible (as you noted), but would force new users to use a more
type-safe approach to the control functions.  Also, in that case, new
ctl codes would not be required.

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



Re: Sadistic C compiler...

2000-01-20 Thread Andy Polyakov

 Hmm.  That's basically an anonymous choice 4 and 5 (depending on ctl
 code).
Yes, that was my vote/proposal. Anonymous/whitened pointer argument is
the key to binary compatibility (at _ctrl level) and having anything
(anything at all) passed by value is not the right thing to do.
 My thought about that one was that BIO_ctrl would be declared
 and defined to take a 'sin_of_ansification *'
 ^ you vote for #4, no star here.
 as argument instead of a
 'void *' (a non-anonymous variant 4).
But it breaks *source* code compatibility and old users gonna get (really)
frustrated.
 This would still be binary
 compatible (as you noted), but would force new users to use a more
 type-safe approach to the control functions. Also, in that case, new
 ctl codes would not be required.
Is a new code a problem?

Andy.

P.S. In reply to previous message.
 Why have it different for o_names.c?
It's uses private interface routines and #4 might be the appropriate
option. Well, "private" means "not likely used by an average OpenSSL
developer."
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-20 Thread Richard Levitte - VMS Whacker

appro  My thought about that one was that BIO_ctrl would be declared
appro  and defined to take a 'sin_of_ansification *'
appro  ^ you vote for #4, no star here.

Oops :-).

appro  as argument instead of a
appro  'void *' (a non-anonymous variant 4).
appro But it breaks *source* code compatibility and old users gonna
appro get (really) frustrated.

That is true, but on the other hand, there have been many discussions
that seem to point to a need to break source compatibility.  That or
doing a triple bendover at some point...  And as far as I understand,
source compatibility has already been broken.

Here's another Decision for us: clean up and break source
compatibility on some points or work really hard at maintaining source
compatibility and building something that has potential of being quite
messy.

appro  This would still be binary
appro  compatible (as you noted), but would force new users to use a more
appro  type-safe approach to the control functions. Also, in that case, new
appro  ctl codes would not be required.
appro Is a new code a problem?

Yes, in a way: it adds to the confusion.  Imagine having to answer the
question "There are two ways to do exactly the same thing.  Why?
Which one is the prefered way?" with something other than "hysterical
raisins" (eh, "historical reasons"...).  There *is* the question of
maintainability, and I sometimes really wonder where we're heading
with that in mind.

appro P.S. In reply to previous message.
appro  Why have it different for o_names.c?
appro It's uses private interface routines and #4 might be the appropriate
appro option. Well, "private" means "not likely used by an average OpenSSL
appro developer."

I've never trusted that kind of assumption.  Especially with the
current state of documentation :-).

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



Re: Sadistic C compiler...

2000-01-19 Thread Andy Polyakov

  And what if sizeof (void (*)()) != sizeof (void *)? Think MS-DOS and all
  those sick small/medium/large/huge memory models if you have to. I
  realize it's a sick thought, but that's what the compiler complains
  about and that's why "such a cast is not permitted by the standard."
 
 In this particular case
  Do you mean DEC C, VMS or something?
 I think the compiler is worried about
 alignment issues.  Functions need to be aligned in a very specific
 way.
So as doubles, longs, integers, shorts (on most platforms). Alignment
requirement for functions aren't extraordinary. I don't have standard
either, but http://www.c9x.org/ used to have draft on-line which is
close enough for any practical purpose. Unfortununately their site looks
messed up right now, but I have a PDF copy at
http://fy.chalmers.se/~appro/c9x-draft.pdf till they get things
straighten out. Relevant quotes:

"7. A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the behavior
is undefined. Otherwise, when converted back again, the result shall
compare equal to the original pointer. When a pointer to an object is
converted to a pointer to a character type, the result points to the
lowest addressed byte of the object. Successive increments of the
result, up to the size of the object, yield pointers to the remaining
bytes of the object.

8. A pointer to a function of one type may be converted to a pointer to
a function of another type and back again; the result shall compare
equal to the original pointer. If a converted pointer is used to call a
function whose type is not compatible with the pointed-to type, the
behavior is undefined."

That's it.

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



Re: Sadistic C compiler...

2000-01-19 Thread Andy Polyakov

 appro Why not simply relax the compiler with /STANDARD=RELAXED or whatever:-)
 
 Sure, we can do that.  Is that the right thing to do?
":-)" was actually ment to designate the wrong thing.
 
 We need to decide if this is something that actually warrants our
 attention, or if we think it can be safely ignored.
My vote is "it should be fixed, eventually."

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



Re: Sadistic C compiler...

2000-01-19 Thread Richard Levitte - VMS Whacker

appro  Why pass a reference?  C has been able to passreturn 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]



Re: Sadistic C compiler...

2000-01-18 Thread Andy Polyakov

 appro  The function pointer *must* be inside a data object to make
 appro  such constructs legal,
 
 appro But that's what Richard (subconsciously?) attempted to do in
 appro first place:
 
 Don't look at me, that part of the code was there in mem.c since
 eons...
Sorry:-) I should have written "whomever who wrote this."
 
 void (*mem_callback)()=(void (*)())cb;
 ...^
 %CC-I-NONSTANDCAST, In the initializer for mem_callback, "cb" of type "pointer to 
char", is being converted to "pointer to function () returning void".  Such a cast is 
not permitted by the standard.
 
 As you can see, whatever you do with the current scheme, there will
 always be a conversion between function pointers and non-function
 pointers.
 
 appro  so this is not silly at all.  An alternative would be to use
 appro  unions of a function pointer
 appro Why structures/unions? "lh_doall_arg(mh,(void (*)())cb_leak,(void
 appro *)mem_cb)" should do...
Look at it more carefully. I don't cast pointer to function, but a
pointer to pointer to function, which is perfectly
portable/legal/legitimate/valid/compliant-with-standard/whatever.
  
 The easiest way to avoid the conversions noted above is to have a
 union like this:
 
 union foo {
 void *simple;
 int (*fn)();
 };
 
 and use it internally.  You put whatever char * you want to convert to
 a functino pointer into simple and pull out the function pointer from
 fn, and vice versa.
Just to make it clear. Are you going to pass the union by reference of
by value? You have to pass by reference which is equivalent to what I
proposed, but without unions. Passing by value would be wrong and
compiler should complain.
 
 appro And I fail to understand why mem_cb has to be declared static?
 
 Not to be seen outside of the file?
The sentence was rather I don't understand why it has to be declared
*outside* CRYPTO_mem_leaks_cb scope. And that's what stands in the next
one:
 appro It can be perfectly declared in CRYPTO_mem_leaks_cb scope which
 appro also makes it multi-thead safe, doesn't it?
 
 appro typedef void (*cb_t) ();
 appro
 appro static void cb_leak(MEM *m, void *cb)
 appro {
 appro void (*mem_callback)()=*((cb_t *)cb);
 
 You convert from void * to void (*)() (i.e. between a "simple
 type" and a function pointer).
Nope, it's cast from a void pointer to pointer to pointer to function
and fetch.
  DEC C will complain.
Shall we bet:-)

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



Re: Sadistic C compiler...

2000-01-18 Thread Andy Polyakov

 bmoeller cb,
 bmoeller on the other hand, is the pointer to some data object; the
 bmoeller function that gets this pointer as an argument has to
 bmoeller retrieve the actual function pointer from inside this data
 bmoeller object, i.e. use *((void (**)()) arg) where arg is the void
 bmoeller * argument passed to it.
Exactly my point. I chose to "typdef void (*cb_t)()" and then "*((cb_t
*)arg)" as it's more readable.
 
 I was pondering such a solution, but I foresaw a problem with it:
 strcmp is the same as strcmp,
Yes, but cb and cb aren't the same at all and we all know that.
 and that might be a difficult bug to find...
Well, just make sure the union is passed by reference and do drop some
comment around it.

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



Re: Sadistic C compiler...

2000-01-18 Thread Richard Levitte - VMS Whacker

bmoeller bit data pointers).  To force C to convert values between
bmoeller these types, you'd have to cast to some integer type inbetween:
bmoeller 
bmoeller (void (*)()) (long) cb

This may very well be a problem on architectures where a pointer is 64
bits while a long is 32 bits.  I think that some versions of Compaq C
on Alpha (VMS and True64) have this quirk...

bmoeller But of course this is so complicated because it should never
bmoeller be done and is not guaranteed to do anything useful.  cb,
bmoeller on the other hand, is the pointer to some data object; the
bmoeller function that gets this pointer as an argument has to
bmoeller retrieve the actual function pointer from inside this data
bmoeller object, i.e. use *((void (**)()) arg) where arg is the void
bmoeller * argument passed to it.

I was pondering such a solution, but I foresaw a problem with it:
strcmp is the same as strcmp, and that might be a difficult bug to
find...

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



Re: Sadistic C compiler...

2000-01-18 Thread Ben Laurie

Richard Levitte - VMS Whacker wrote:
 The easiest way to avoid the conversions noted above is to have a
 union like this:
 
 union foo {
 void *simple;
 int (*fn)();
 };
 
 and use it internally.  You put whatever char * you want to convert to
 a functino pointer into simple and pull out the function pointer from
 fn, and vice versa.

That assumes that the conversion the compiler is attempting to prevent
can actually be done, which is not, of course, a valid assumption. The
only way to do this validly is to make the functions actually take a foo
* as their argument, surely? And yes, then you may end up with a memory
management problem (though often not, coz I'll bet in most cases you can
make the foo static).

Cheers,

Ben.

--
SECURE HOSTING AT THE BUNKER! http://www.thebunker.net/hosting.htm

http://www.apache-ssl.org/ben.html

"My grandfather once told me that there are two kinds of people: those
who work and those who take the credit. He told me to try to be in the
first group; there was less competition there."
 - Indira Gandhi
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-18 Thread Richard Levitte - VMS Whacker

appro Just to make it clear. Are you going to pass the union by
appro reference of by value? You have to pass by reference which is
appro equivalent to what I proposed, but without unions. Passing by
appro value would be wrong and compiler should complain.

As you have probably seen by now, I don't pass around any unions at
all, I just use them as instruments to convert pointers.  You see, I
absolutely wanted to keep binary compatibility for now, or we would
see a lot of things break silently all over the place, since most of
these things happen in places where regular char pointers are passed
as parameters as well (the diverse _ctrl() functions, for example).

But it's very possible that we can make things more elegant, and also
more complicated.  We most apparently have pointers "of variable
type", which basically is a union.  For those parameters, we could
simply enforce the use of a union, and provide a few macros to make it
easier to handle.  (oh, and yes, before you ask, in my min that union
would be passed around by reference :-), but then we have the problem
of handling temporary instances nicely)

appro   DEC C will complain.

appro Shall we bet:-)

Nope, you were right about that one.

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



Re: Sadistic C compiler...

2000-01-18 Thread Dr Stephen Henson

Ben Laurie wrote:
 
 Richard Levitte - VMS Whacker wrote:
  The easiest way to avoid the conversions noted above is to have a
  union like this:
 
  union foo {
  void *simple;
  int (*fn)();
  };
 
  and use it internally.  You put whatever char * you want to convert to
  a functino pointer into simple and pull out the function pointer from
  fn, and vice versa.
 
 That assumes that the conversion the compiler is attempting to prevent
 can actually be done, which is not, of course, a valid assumption. The
 only way to do this validly is to make the functions actually take a foo
 * as their argument, surely? And yes, then you may end up with a memory
 management problem (though often not, coz I'll bet in most cases you can
 make the foo static).
 

Hmmm. Do we have to use this on every platform, including those that
handled it before?

Can't we just have a macro or function that does the conversion? I.e. on
most platforms it would be a macro which expands to a cast but on VMS it
would end up calling a function.

Steve.
-- 
Dr Stephen N. Henson.   http://www.drh-consultancy.demon.co.uk/
Personal Email: [EMAIL PROTECTED] 
Senior crypto engineer, Celo Communications: http://www.celocom.com/
Core developer of the   OpenSSL project: http://www.openssl.org/
Business Email: [EMAIL PROTECTED] PGP key: via homepage.

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



Re: Sadistic C compiler...

2000-01-18 Thread Andy Polyakov

 appro Just to make it clear. Are you going to pass the union by
 appro reference of by value? You have to pass by reference which is
 appro equivalent to what I proposed, but without unions. Passing by
 appro value would be wrong and compiler should complain.
 
 As you have probably seen by now, I don't pass around any unions at
 all, I just use them as instruments to convert pointers.
And what if sizeof (void (*)()) != sizeof (void *)? Think MS-DOS and all
those sick small/medium/large/huge memory models if you have to. I
realize it's a sick thought, but that's what the compiler complains
about and that's why "such a cast is not permitted by the standard."
 You see, I
 absolutely wanted to keep binary compatibility for now, or we would
 see a lot of things break silently all over the place,
Why not simply relax the compiler with /STANDARD=RELAXED or whatever:-)

Cheers. Andy.
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-18 Thread Jeffrey Altman

 And what if sizeof (void (*)()) != sizeof (void *)? Think MS-DOS and all
 those sick small/medium/large/huge memory models if you have to. I
 realize it's a sick thought, but that's what the compiler complains
 about and that's why "such a cast is not permitted by the standard."

In this particular case I think the compiler is worried about
alignment issues.  Functions need to be aligned in a very specific
way.



Jeffrey Altman * Sr.Software Designer * Kermit-95 for Win32 and OS/2
 The Kermit Project * Columbia University
  612 West 115th St #716 * New York, NY * 10025
  http://www.kermit-project.org/k95.html * [EMAIL PROTECTED]


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



Re: Sadistic C compiler...

2000-01-18 Thread Andy Polyakov

   The easiest way to avoid the conversions noted above is to have a
   union like this:
  
   union foo {
   void *simple;
   int (*fn)();
   };
  
   and use it internally.  You put whatever char * you want to convert to
   a functino pointer into simple and pull out the function pointer from
   fn, and vice versa.
 
  That assumes that the conversion the compiler is attempting to prevent
  can actually be done, which is not, of course, a valid assumption. The
  only way to do this validly is to make the functions actually take a foo
  * as their argument, surely? And yes, then you may end up with a memory
  management problem (though often not, coz I'll bet in most cases you can
  make the foo static).
 
 
 Hmmm. Do we have to use this on every platform, including those that
 handled it before?
 
 Can't we just have a macro or function that does the conversion? I.e. on
 most platforms it would be a macro which expands to a cast but on VMS it
 would end up calling a function.
It's *not* VMS specific! DEC C 6.2 for Unix issues very similar warning.
Yes, it's just a warning, it's not a fatal error and generated code does
the intended thing. It should also be pointed out that it (Unix version)
does it only if invoked with -std1 flag which stands for maximum
standard compliance! Do we have to use on every platform? Only if we
want to claim that the toolkit is 100% ANSI C:-) For your information
here're other offending casts:

cc: Info: bss_conn.c, line 573: In this statement, "data-info_callback"
of type
 "pointer to function () returning int", is being converted to "pointer
to char"
.  Such a cast is not permitted by the standard. (nonstandcast)
(void)BIO_set_info_callback(dbio,data-info_callback);
--^
cc: Info: bss_conn.c, line 576: In this statement, "ptr" of type
"pointer to cha
r", is being converted to "pointer to function () returning int".  Such
a cast i
s not permitted by the standard. (nonstandcast)
data-info_callback=(int (*)())ptr;
---^
cc: Info: o_names.c, line 53: In this statement, "strcmp" of type
"pointer to fu
nction (pointer to const char, pointer to const char) returning int", is
being c
onverted to "pointer to char".  Such a cast is not permitted by the
standard. (n
onstandcast)
sk_push(names_hash,(char *)strcmp);
---^
cc: Info: o_names.c, line 54: In this statement, "lh_strhash" of type
"pointer t
o function (pointer to const char) returning unsigned long", is being
converted 
to "pointer to char".  Such a cast is not permitted by the standard.
(nonstandca
st)
sk_push(names_cmp,(char *)lh_strhash);
--^
cc: Info: o_names.c, line 59: In this statement, "hash_func" of type
"pointer to
 function () returning unsigned long", is being converted to "pointer to
char". 
 Such a cast is not permitted by the standard. (nonstandcast)
sk_set(names_hash,ret,(char *)hash_func);
--^
cc: Info: o_names.c, line 61: In this statement, "cmp_func" of type
"pointer to 
function () returning int", is being converted to "pointer to char". 
Such a cas
t is not permitted by the standard. (nonstandcast)
sk_set(names_cmp,ret,(char *)cmp_func);
-^
cc: Info: o_names.c, line 63: In this statement, "free_func" of type
"pointer to
 function () returning void", is being converted to "pointer to char". 
Such a c
ast is not permitted by the standard. (nonstandcast)
sk_set(names_free,ret,(char *)free_func);
--^
cc: Info: o_names.c, line 77: In this statement, "sk_value(...)" of type
"pointe
r to char", is being converted to "pointer to function () returning
int".  Such 
a cast is not permitted by the standard. (nonstandcast)
cmp=(int (*)())sk_value(names_cmp,a-type);
---^
cc: Info: o_names.c, line 93: In this statement, "sk_value(...)" of type
"pointe
r to char", is being converted to "pointer to function () returning
unsigned lon
g".  Such a cast is not permitted by the standard. (nonstandcast)
hash=(unsigned long (*)())sk_value(names_hash,a-type);
--^
cc: Info: o_names.c, line 163: In this statement, "sk_value(...)" of
type "point
er to char", is being converted to "pointer to function () returning
void".  Suc
h a cast is not permitted by the standard. (nonstandcast)
f=(void (*)())sk_value(names_free,ret-type);
--^
cc: Info: o_names.c, line 195: In this statement, "sk_value(...)" of
type "point
er to char", is being converted to "pointer to function () returning
void".  Suc
h a cast is not permitted by the standard. 

RE: Sadistic C compiler...

2000-01-18 Thread Salz, Rich

Why pass a reference?  C has been able to passreturn aggregate types since
v7 :)

only way to do this validly is to make the functions
actually take a foo* as their argument, surely?

Yes you must do that.

I'll bet in most cases you can make the foo static

Unless I misunderstand what you mean, that's not thread-safe.
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-18 Thread Michael Sierchio

Jeffrey Altman wrote:

   .
  4  fn(x,  y,  z);/*  Function  call: functions   */
   /*  x  and  y,  and  array  z   */
   /*  passed  as  addresses */


A function pointer may not be an "address" -- in particular,  on segmented
architectures,  a function pointer may not resolve to any regular
storage class for the compiler/platform combo.  Another reason not
to try to cast function pointers ...


-- 
QUI ME AMET, CANEM MEUM ETIAM AMET
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-18 Thread Richard Levitte - VMS Whacker

appro Why not simply relax the compiler with /STANDARD=RELAXED or whatever:-)

Sure, we can do that.  Is that the right thing to do?  I remember that
at some point, it was "all hail ANSI C", something I support.  But not
only that, if this problem is enough to actually create errors on
"MS-DOS and all those sick small/medium/large/huge memory models" or
on other segmented architectures (I don't know that many, but...), is
it then the right thing to tell the compiler to shut up so we don't
have to bother with it.

We need to decide if this is something that actually warrants our
attention, or if we think it can be safely ignored.

(I personally don't mind relaxing DEC C a bit, although it will
sometimes take away half the fun :-).  I know it will work correctly
on VMS...  and on the Unixen I play with)

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



Re: Sadistic C compiler...

2000-01-18 Thread Bodo Moeller

On Tue, Jan 18, 2000 at 10:59:53AM +0100, Richard Levitte - VMS Whacker wrote:

 bit data pointers).  To force C to convert values between
 these types, you'd have to cast to some integer type inbetween:

 (void (*)()) (long) cb

 This may very well be a problem on architectures where a pointer is 64
 bits while a long is 32 bits.

Exactly, which is why compilers should complain when someone attempts
to do such things (with just one cast, as in OpenSSL -- two casts as
above tell the compiler that the user pretends to know what he is
doing).

 But of course this is so complicated because it should never
 be done and is not guaranteed to do anything useful.  cb,
 on the other hand, is the pointer to some data object; the
 function that gets this pointer as an argument has to
 retrieve the actual function pointer from inside this data
 object, i.e. use *((void (**)()) arg) where arg is the void
 * argument passed to it.

 I was pondering such a solution, but I foresaw a problem with it:
 strcmp is the same as strcmp, and that might be a difficult bug to
 find...

I see, this could become a problem (when using over-tolerant compilers
that don't print warnings for such conversions).
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



RE: Sadistic C compiler...

2000-01-18 Thread Jeffrey Altman

 Looks like a compiler bug; NULL is supposed to be safely castable to any
 pointer type, and compared against any pointer type.

NULL is often a pound define and not a compiler name.  Its definition
is very frequently

  (char *)0

which is not comparable.



Jeffrey Altman * Sr.Software Designer * Kermit-95 for Win32 and OS/2
 The Kermit Project * Columbia University
  612 West 115th St #716 * New York, NY * 10025
  http://www.kermit-project.org/k95.html * [EMAIL PROTECTED]


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



RE: Sadistic C compiler...

2000-01-18 Thread Richard Levitte - VMS Whacker

SalzR Looks like a compiler bug; NULL is supposed to be safely
SalzR castable to any pointer type, and compared against any pointer
SalzR type.

Depends on.  If NULL is defined like this:

#define NULL 0

then you're perfectly right, but if it's defined like this:

#define NULL ((void *)0)

then I'm dubious at least.  I don't have the standard here, but I'm
pretty sure it says that 0 can be cast to any pointer, not necessarely
NULL.  Compaq C did of course not complain when I replaced NULL with
0.

Have you noticed, if you read The C++ Programming Language, how he
completely avoids NULL and consequently uses 0 instead?  I think he's
got at least one clue on this issue.

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



Re: Sadistic C compiler...

2000-01-18 Thread Ben Laurie

"Salz, Rich" wrote:
 
 Why pass a reference?  C has been able to passreturn aggregate types since
 v7 :)

Good point.

 only way to do this validly is to make the functions
 actually take a foo* as their argument, surely?
 
 Yes you must do that.
 
 I'll bet in most cases you can make the foo static
 
 Unless I misunderstand what you mean, that's not thread-safe.

It is if the function is always the same (which is what I meant).

Cheers,

Ben.

--
SECURE HOSTING AT THE BUNKER! http://www.thebunker.net/hosting.htm

http://www.apache-ssl.org/ben.html

"My grandfather once told me that there are two kinds of people: those
who work and those who take the credit. He told me to try to be in the
first group; there was less competition there."
 - Indira Gandhi
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



RE: Sadistic C compiler...

2000-01-18 Thread Salz, Rich


In the ANSI standard C sense, there is no real difference between the C
language and the supporting libraries.
I don't have a copy of the standard handy, but I'm fairly sure it can be
safely castable as I said before.

Therefore if Compaq's C compiler #define's it as void*,
then their "compiler" seems to have a bug.
/r$
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-18 Thread Bodo Moeller

Richard Levitte - VMS Whacker [EMAIL PROTECTED]:

[...]
 The easiest way to avoid the conversions noted above is to have a
 union like this:
 
   union foo {
   void *simple;
   int (*fn)();
   };
 
 and use it internally.  You put whatever char * you want to convert to
 a functino pointer into simple and pull out the function pointer from
 fn, and vice versa.

You cannot convert things this way, that would be just as broken as
using casts.  What you can do, of course, is put pointers into the
appropriate union member ('simple' for data pointers, 'fn' for
function pointers), pass the union to some function, and, in this
function, take the same union member from the union passed as an
argument.  I thought you had done exactly that, but a second look in
the commitlog shows that you have not (and it would make SSL_[CTX_]ctrl
much more complicated, we'd have to change the prototype).

The clean way (and not just another "clever hack") would be

void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
  int is_export,
  int keylength))
{
RSA *(**cb_ptr)(SSL *, int, int) = cb; /* cb_ptr is a data pointer,
 * not a function pointer */
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,0,cb_ptr); /* no cast necessary as
 * SSL_CTX_ctrl should
 * have "void *" in the
 * final argument */
}

and in ssl3_ctrl (which is what SSL_CTX_ctrl ends up calling):

long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
{
[...]

switch (cmd)
{
[...]

case SSL_CTRL_SET_TMP_RSA_CB:
{
RSA *(**cb_ptr)(SSL *, int, int) = parg;

s-cert-rsa_tmp_cb = *cb_ptr;
}
break;
[...]
}
[...]
}

Instead of directly passing function pointers in disguise, a pass
pointers to data objects containing the actual function pointers.

Note that I'm using temporary variables instead of single-line
commands involving casts because this way it can be hoped more
compilers will print warnings or error messages in case of a typo --
the explicit cast from a function pointer value to void * was enough
to bring gcc to silence, but without casts the compiler can see that
you don't really intend to do such evil things.
(SSL_CTX_ctrl, ssl3_ctrl et al. still have a char * argument where
they should have a void * -- it's certainly trivial to change that.)
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



RE: Sadistic C compiler...

2000-01-18 Thread Richard Levitte - VMS Whacker

SalzR In the ANSI standard C sense, there is no real difference
SalzR between the C language and the supporting libraries.

It's useless to discuss it unless someone can cite the exact words of
the standard here.  Until then, we're just talking out of our behinds.

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



Re: Sadistic C compiler...

2000-01-18 Thread Dr Stephen Henson

Richard Levitte - VMS Whacker wrote:
 
 SalzR In the ANSI standard C sense, there is no real difference
 SalzR between the C language and the supporting libraries.
 
 It's useless to discuss it unless someone can cite the exact words of
 the standard here.  Until then, we're just talking out of our behinds.
 

That's never stopped us before :-)

Steve.
-- 
Dr Stephen N. Henson.   http://www.drh-consultancy.demon.co.uk/
Personal Email: [EMAIL PROTECTED] 
Senior crypto engineer, Celo Communications: http://www.celocom.com/
Core developer of the   OpenSSL project: http://www.openssl.org/
Business Email: [EMAIL PROTECTED] PGP key: via homepage.


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



Re: Sadistic C compiler...

2000-01-18 Thread Dr Stephen Henson

Bodo Moeller wrote:
 
 
 The clean way (and not just another "clever hack") would be
 
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
   int is_export,
   int keylength))
 {
 RSA *(**cb_ptr)(SSL *, int, int) = cb; /* cb_ptr is a data pointer,
  * not a function pointer */
 SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,0,cb_ptr); /* no cast necessary as
  * SSL_CTX_ctrl should
  * have "void *" in the
  * final argument */
 }
 
 and in ssl3_ctrl (which is what SSL_CTX_ctrl ends up calling):
 
 long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 {
 [...]
 
 switch (cmd)
 {
 [...]
 
 case SSL_CTRL_SET_TMP_RSA_CB:
 {
 RSA *(**cb_ptr)(SSL *, int, int) = parg;
 
 s-cert-rsa_tmp_cb = *cb_ptr;
 }
 break;
 [...]
 }
 [...]
 }
 
 Instead of directly passing function pointers in disguise, a pass
 pointers to data objects containing the actual function pointers.
 

Hmmm that will change the SSL_ctrl() behaviour but that shouldn't be
called directly anyway.

The BIOs are a little more awkward for example we've got
BIO_set_info_callback() currently defined as a macro casting the
callback to (char *). I'd suggest we use a similar technique and zap the
macro. The macros that do this kind of thing want replacing with real
functions anyway.

It will break binary compatibility but I can't think of any alternative.
It shouldn't matter too much anyway. So much has changed since 0.9.4
most application should be recompiled anyway.

I can't think of anywhere where we have a stack of function pointers. 
The EX_DATA stuff has them wrapped up in a strucure. Hmm... I've just
had a look, its a plain STACK, not STACK_OF and has no prototypes on the
function pointers either. It needs fixing.

 (SSL_CTX_ctrl, ssl3_ctrl et al. still have a char * argument where
 they should have a void * -- it's certainly trivial to change that.)

Yes thats a legacy from the pre-ANSI days. It, and a few others, should
be changed and a few (char *) casts deleted as well.

Steve.
-- 
Dr Stephen N. Henson.   http://www.drh-consultancy.demon.co.uk/
Personal Email: [EMAIL PROTECTED] 
Senior crypto engineer, Celo Communications: http://www.celocom.com/
Core developer of the   OpenSSL project: http://www.openssl.org/
Business Email: [EMAIL PROTECTED] PGP key: via homepage.

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



Re: Sadistic C compiler...

2000-01-17 Thread Steve Sampson

 
 DEC C for VMS is getting really mean.

There's a reason DEC went out of business :-)

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



Re: Sadistic C compiler...

2000-01-17 Thread Bodo Moeller

On Mon, Jan 17, 2000 at 01:06:27AM +0100, Richard Levitte - VMS Whacker wrote:

 DEC C for VMS is getting really mean.  Version 6.2 (latest, as far as
 I know) spews out a message when a (char *) cast is done to a function
 pointer and vice versa.

Every compiler should print such warnings, such casts are by no means
guaranteed to work.

 It's especially visible in all the places where lh_doall_arg() gets a
 casted function pointer as last argument (for example, see
 CRYPTO_mem_leaks_cb() in crypto/mem_dbg.c)...
 
 I can imagine using silly things like a struct around the function
 pointer to get rid of that warning.

The function pointer *must* be inside a data object to make such constructs
legal, so this is not silly at all.  An alternative would be to use
unions of a function pointer and a data pointer (casts between
different function pointer types are legal, you just have to make
sure that you call the function as the same type as it was originally
defined -- OpenSSL even fails at this) instead of just a void *,
but that's probably more complicated than depositing the function pointer
in a struct.
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: Sadistic C compiler...

2000-01-17 Thread Dr Stephen Henson

Richard Levitte - VMS Whacker wrote:
 
 DEC C for VMS is getting really mean.  Version 6.2 (latest, as far as
 I know) spews out a message when a (char *) cast is done to a function
 pointer and vice versa.  Guess what it finds a little here and there
 in OpenSSL?  :-)
 
 Changing (char *) to (void *) (that has been know to do magic
 sometimes) doesn't help.
 

Hmmm. Does VMS have an equivalent to shared libraries which can be
loaded at runtime? If so how is that handled? There's normally a
function in there that has to return a value that can be cast into any
function pointer.

Steve.
-- 
Dr Stephen N. Henson.   http://www.drh-consultancy.demon.co.uk/
Personal Email: [EMAIL PROTECTED] 
Senior crypto engineer, Celo Communications: http://www.celocom.com/
Core developer of the   OpenSSL project: http://www.openssl.org/
Business Email: [EMAIL PROTECTED] PGP key: via homepage.

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



Re: Sadistic C compiler...

2000-01-17 Thread Andy Polyakov

  DEC C for VMS is getting really mean. Version 6.2
  ^^^ It has nothing to do with VMS. It complains about
casts between (*) and * even on Unix.
 
  It's especially visible in all the places where lh_doall_arg() gets a
  casted function pointer as last argument (for example, see
  CRYPTO_mem_leaks_cb() in crypto/mem_dbg.c)...
 
  I can imagine using silly things like a struct around the function
  pointer to get rid of that warning.
 
 The function pointer *must* be inside a data object to make such constructs
 legal,
But that's what Richard (subconsciously?) attempted to do in first
place:

static void (*mem_cb)()=NULL;

void CRYPTO_mem_leaks_cb(void (*cb)())
{
...
mem_cb=cb;
lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb);
mem_cb=NULL;
...
}

I mean someting has prevented him from just "lh_doall_arg(mh,(void
(*)())cb_leak,(char *)cb)," hasn't it?
 so this is not silly at all.  An alternative would be to use
 unions of a function pointer
Why structures/unions? "lh_doall_arg(mh,(void (*)())cb_leak,(void
*)mem_cb)" should do... Of course provided that it's appropriately
derefenced in cb_leak! And I fail to understand why mem_cb has to be
declared static? It can be perfectly declared in CRYPTO_mem_leaks_cb
scope which also makes it multi-thead safe, doesn't it? To summarize:

typedef void (*cb_t) ();

static void cb_leak(MEM *m, void *cb)
{
void (*mem_callback)()=*((cb_t *)cb);
mem_callback(m-order,m-file,m-line,m-num,m-addr);
}

void CRYPTO_mem_leaks_cb(void (*cb)())
{
void (*mem_cb)() = cb;
if (mh == NULL) return;
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
lh_doall_arg(mh,(void (*)())cb_leak,(void *)(mem_cb));
CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
}

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



Re: Sadistic C compiler...

2000-01-17 Thread Richard Levitte - VMS Whacker

bmoeller The function pointer *must* be inside a data object to make
bmoeller such constructs legal, so this is not silly at all.

Perfectly right.  My "silly" wasn't completely serious...

Anyway, thanks for the input, it confirmed that my thoughts were
right.  Time to hack :-).

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



Re: Sadistic C compiler...

2000-01-17 Thread Richard Levitte - VMS Whacker

ssampson  DEC C for VMS is getting really mean.
ssampson 
ssampson There's a reason DEC went out of business :-)

True.  However, that's not it.  DEC software has had a tendency to
hold quite high quality, and it seems that Compaq will keep that.

Sorry, but you really shot the wrong dog here...

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



Re: Sadistic C compiler...

2000-01-17 Thread Richard Levitte - VMS Whacker

drh Hmmm. Does VMS have an equivalent to shared libraries which can
drh be loaded at runtime?

drh If so how is that handled?

Looks like this:

int status = LIB$FIND_FILE_SYMBOL(lib_file, symbol_name,
  symbol_address, dir_spec, flags);

The secret is that LIB$FIND_FILE_SYMBOL is declared as having unknown
parameters (...), so you can give it whatever you like in there.  The
routine is pretty good at checking that the arguments make sense.

drh There's normally a function in there that has to return a value
drh that can be cast into any function pointer.

Doesn't help much in this case, does it ?  :-)

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



Re: Sadistic C compiler...

2000-01-17 Thread Richard Levitte - VMS Whacker

appro  The function pointer *must* be inside a data object to make
appro  such constructs legal,

appro But that's what Richard (subconsciously?) attempted to do in
appro first place:

Don't look at me, that part of the code was there in mem.c since
eons...

appro static void (*mem_cb)()=NULL;
appro 
appro void CRYPTO_mem_leaks_cb(void (*cb)())
appro {
appro ...
appro mem_cb=cb;
appro lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb);
appro mem_cb=NULL;
appro ...
appro }
appro 
appro I mean someting has prevented him from just "lh_doall_arg(mh,(void
appro (*)())cb_leak,(char *)cb)," hasn't it?

I Actually don't know why Eric needed to do that.  But just for
clarity, let me show you what DEC C says:

void (*mem_callback)()=(void (*)())cb;
...^
%CC-I-NONSTANDCAST, In the initializer for mem_callback, "cb" of type "pointer to 
char", is being converted to "pointer to function () returning void".  Such a cast is 
not permitted by the standard.
at line number 668 in file 
DISK$ALPUTILS:[LEVITTE.WRK.OPENSSL-0_9_5-DEV.CRYPTO]MEM_DBG.C;3

lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb);
^
%CC-I-NONSTANDCAST, In this statement, "mem_cb" of type "pointer to function () 
returning void", is being converted to "pointer to char".  Such a cast is not 
permitted by the standard.
at line number 677 in file 
DISK$ALPUTILS:[LEVITTE.WRK.OPENSSL-0_9_5-DEV.CRYPTO]MEM_DBG.C;3


As you can see, whatever you do with the current scheme, there will
always be a conversion between function pointers and non-function
pointers.

appro  so this is not silly at all.  An alternative would be to use
appro  unions of a function pointer
appro Why structures/unions? "lh_doall_arg(mh,(void (*)())cb_leak,(void
appro *)mem_cb)" should do...

The easiest way to avoid the conversions noted above is to have a
union like this:

union foo {
void *simple;
int (*fn)();
};

and use it internally.  You put whatever char * you want to convert to
a functino pointer into simple and pull out the function pointer from
fn, and vice versa.

appro Of course provided that it's appropriately derefenced in
appro cb_leak!

As you can see above, that's exactly one of the problems.

appro And I fail to understand why mem_cb has to be declared static?

Not to be seen outside of the file?

appro It can be perfectly declared in CRYPTO_mem_leaks_cb scope which
appro also makes it multi-thead safe, doesn't it?

You're absolutely right about, but that is beside the point in this
case.  This is a ANSI C problem, not a MT problem.

appro typedef void (*cb_t) ();
appro 
appro static void cb_leak(MEM *m, void *cb)
appro {
appro void (*mem_callback)()=*((cb_t *)cb);

You convert from void * to void (*)() (i.e. between a "simple
type" and a function pointer).  DEC C will complain.

appro mem_callback(m-order,m-file,m-line,m-num,m-addr);
appro }
appro 
appro void CRYPTO_mem_leaks_cb(void (*cb)())
appro {
appro void (*mem_cb)() = cb;
appro if (mh == NULL) return;
appro CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
appro lh_doall_arg(mh,(void (*)())cb_leak,(void *)(mem_cb));

You convert from void (*)() to void * (i.e. between a "simple
type" and a function pointer).  DEC C will complain.

appro CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
appro }

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



Re: Sadistic C compiler...

2000-01-17 Thread Richard Levitte - VMS Whacker

BTW, I just discovered the following (about crypto/x509v3/v3_int.c):

(X509V3_EXT_S2I)NULL,
^
%CC-I-NONSTANDCAST, In the initializer for v3_crl_num.s2i, "((void ...)0)" of type 
"pointer to void", is being converted to "pointer to function (pointer to struct 
v3_ext_method, pointer to struct v3_ext_ctx, pointer to char) returning pointer to 
void".  
Such a cast is not permitted by the standard.
at line number 70 in file 
DISK$ALPUTILS:[LEVITTE.WRK.OPENSSL-0_9_5-DEV.CRYPTO.X509V3]V3_INT.C;1


that hurt...

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



Re: Sadistic C compiler...

2000-01-17 Thread Jeffrey Altman

And more text:

5.6.2  Function and Array Identifiers as Arguments
  Function and array identifiers can be specified as argu-
  ments to a function.  Function identifiers are specified without
  parentheses, and array identifiers are specified without
  brackets.  When so specified, the function or array identifier
  is evaluated as the address of that function or array.  Also, the
  function must be declared or defined, even if its return value
  is an integer. Example 5-1   shows how and when to declare
  functions passed as arguments, and how to pass them.

  Key to Example 5-1:

   1  Without being declared in a separate declaration, function
  x can be passed in an argument list because its defi-
  nition, located before the function caller, serves as its
  declaration.

   2  Parameters that represent functions can be declared ei-
  ther as functions or as pointers to functions.  Parameters
  that represent arrays can be declared either as arrays or
  as pointers to the element type of the array.  For example:
  fn(int  f1(),  int  f2(),  int  a1[])   /*  f1,  f2
declared  as  */

  {...}/*  functions;  a1
declared  */
   /*  as  array  of
int.  */

  fn(int  (*f1)(),  int  (*f2)(),  int  *a1)  /*  f1,  f2
declared  as  */
  {...}/*  pointers  to
functions;  */
   /*  a1  declared  as
pointer  */
   /*  to  int.
 */

  When such parameters are declared as functions or
  arrays, the compiler automatically converts the corre-
  sponding arguments to pointers.

   3  Because its function definition is located after the function
  caller, function y must be declared before passing it in an
  argument list.

   4  When passing functions as arguments, do not include
  parentheses.  Similarly, when specifying arrays, do not
  include subscripts.

  Example 5-1:  Declaring Functions Passed as Arguments

 1  int  x()   {  return  25;  }   /*  Function  definition  and */
int  z[10];/*  array  defined  before use   */

 2  fn(int  f1(),  int  (*f2)(),  int  a1[])) /*  Function definition  */
{
f1();  /*  Call  to  function  f1 */
  .
  .
  .
}

void  caller(void)
{
 3  int  y();  /*  Function  declaration */
  .
  .
  .
 4  fn(x,  y,  z);/*  Function  call: functions   */
  /*  x  and  y,  and  array  z   */
  /*  passed  as  addresses */
  .
  .
  .
}

int  y(void)  {  return  30;  }   /*  Function  definition  */

6.11.2  Pointer Conversions
  Although two types (for example,int and  long) can have
  the same representation, they are still different types.  This
  means that a pointer to   int cannot be assigned to a pointer
  to long without using a cast.  Nor can a pointer to a func-
  tion of one type be assigned to a pointer to a function of a
  different type without using a cast.  In addition, pointers to
  functions that have different parameter-type information,
  including the old-style absence of parameter-type informa-
  tion, are different types.  In these instances, if a cast is not
  used, the compiler issues an error.  Because there are align-
  ment restrictions on some target processors, access through
  an unaligned pointer can result in a much slower access time
  or a machine exception.

  A pointer to void can be converted to or from a pointer to
  any incomplete or object type.  If a pointer to any incomplete
  or object type is converted to a pointer to void and back, the
  result compares equal to the original pointer.

  An integral constant expression equal to 0, or such an expres-
  sion cast to thevoid * type, is called anull pointer constant.  If
  a null pointer constant is assigned to or compared for equality
  with a pointer, the constant is converted to a pointer of that
  type.  Such a pointer is called anull pointer, and is guaranteed
  to compare unequal to a pointer to any object or function.

  An array designator is automatically converted to a pointer to
  the array type, and the pointer points to the first element of
  the array.




Jeffrey Altman * Sr.Software Designer * Kermit-95 for Win32 and OS/2
 The Kermit Project * Columbia University
  612 West 115th St #716 * New York, NY * 10025
  http://www.kermit-project.org/k95.html * [EMAIL PROTECTED]


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

Re: Sadistic C compiler...

2000-01-17 Thread Bodo Moeller

Andy Polyakov [EMAIL PROTECTED]:

 The function pointer *must* be inside a data object to make such constructs
 legal,

 But that's what Richard (subconsciously?) attempted to do in first
 place:
 
 static void (*mem_cb)()=NULL;
 
 void CRYPTO_mem_leaks_cb(void (*cb)())
 {
 ...
 mem_cb=cb;
 lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb);
 mem_cb=NULL;
 ...
 }

That's weird, I did not notice this and don't know why he did it this way
(and probably he doesn't either :-).

This is however not what I meant, this is just like calling

 lh_doall_arg(mh,(void (*)())cb_leak,(char *)cb);

without using the extra static variable.  We're still passing
a function pointer value.  What would work, however, is

 void CRYPTO_mem_leaks_cb(void (*cb)())
 {
 ...
 void *cb_ptr=cb;
 lh_doall_arg(mh,(void (*)())cb_leak,cb);
 ...
 }

(there's no reason to introduce a struct unless one wants to do things
over-complicated, I don't know why I mentioned structs before).
The point is that C doesn't like mixing function pointers and data
object pointers; they don't necessarily have identical
representations (you could have 32 bit function pointers, but 64
bit data pointers).  To force C to convert values between these types,
you'd have to cast to some integer type inbetween:

(void (*)()) (long) cb

But of course this is so complicated because it should never be done
and is not guaranteed to do anything useful.  cb, on the other hand,
is the pointer to some data object; the function that gets this
pointer as an argument has to retrieve the actual function pointer
from inside this data object, i.e. use *((void (**)()) arg)
where arg is the void * argument passed to it.
__
OpenSSL Project http://www.openssl.org
Development Mailing List   [EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]