"
Length is not the issue. There is no rule that says that two types must be
passed the same way just because they're the same length. For example, some
platforms may pass a 64-bit floating point number in a floating point
register but pass a 64-bit integer in an integer register.
"

I'm not sure that's true, it's an optimization sure, but C doesn't care
about type. So there are optimizations that aren't legal for the C
language.
In this case I can't see a problem.
Sure if you were passing either a float or a long, which happened to be the
same size and you had a dedicated FPU register I can see a problem, (though
I suspect even in this case the optimzation is dubious for C ) but in this
case the ambiguity is at the thing the pointer points to. Any optimization
here would be in the called function - either loading the thing the pointer
points to into an integer or FPU register. They can't have separate address
spaces or this would be impossible:

typedef struct {
float f;
long l;
} X;

"
You are correct, but that's not the issue. The issue is this simple -- if
you are going to call a function whose types you don't know (through a
prototype), you must cast each type you pass to the type the function
expects. End of story. OpenSSL does not do this. This is not valid C
whether
or not the type sizes are the same.
"

Sorry, I think it's a compiler bug. The compiler DOES know the types of the
arguments in every case, it's what they are declared to be by default, it
even has the information necessary to decide the register the arguments
should be passed in (WRT to the FPU register argument above.)
Yes the programmer *might* have screwed up, but that's not the compiler
writers call. Emit a warning by all means but this is resolvable at compile
time.

And saying it's the compilers job to catch this is bogus as well, I can
cast the function to the wrong type and cause exactly the problems at
runtime that this "optimization" is supposed to protect against.

"
Can you cite anything in the C standard that says this is allowed? As I
understand it, you must pass a function precisely the types it expects, or
use a prototype to force the compiler to cast them. Either way, the exact
type must be known where the call is compiled.
"

printf() still works and that disagrees with your view of the universe.

And as noted above, the function is prototyped, just not explicitly,
assuming the programmer got the argument types correct and the type of the
variable holding the return value you have an implicit (and sufficient)
function prototype.
You can't have no function prototype at all at the point you make the call
in C. Yes, you can get it wrong and crash, but historically that's been the
programmers responsibility.

Your argument IS valid for C++, but I'm not yet convinced it's correct for
C.

Peter

https://cs.opensource.ibm.com/projects/icc




"David Schwartz"
.com> To
Sent by:
owner-openssl-dev cc
@openssl.org
Subject
RE: OpenSSL breaks with gcc 4.2
09/11/06 03:59 PM


Please respond to
openssl-dev







> x is still just a pointer to data - so it's the same
> length in any case, all pointers to lvalues are the
> same length in C. The only issue there is whether it's
> aligned correctly - that's the programmers problem.


Length is not the issue. There is no rule that says that two types must be
passed the same way just because they're the same length. For example, some
platforms may pass a 64-bit floating point number in a floating point
register but pass a 64-bit integer in an integer register.

All you can do is assume that it will work because it has always worked,
until it stops working.

> Mixing something like char *(*d2i)(), and char ** IS
> problematic, since those aren't guaranteed to be the
> same length but as far as I can remember OpenSSL doesn't
> do that.


If they are not the same length, it is not likely to work. That doesn't
mean
it's legal if they are the same length.

> ret=d2i(x,&p,len);


> d2i is a function (prototype is unknown)
> but I've been told x is a pointer, &p is a pointer,
> len is long. There's nothing indeterminate about the
> size of any of those.


The issue is not size, it's type.

> C isn't a strongly typed language - there's no language
> requirement for an accurate function prototype or that
> the types of the arguments be correct - only that the
> size of them is correct.


You are correct, but that's not the issue. The issue is this simple -- if
you are going to call a function whose types you don't know (through a
prototype), you must cast each type you pass to the type the function
expects. End of story. OpenSSL does not do this. This is not valid C
whether
or not the type sizes are the same.

> C is not the same language as C++, this instance should
> work with a C compiler - whether or not the compiler is
> passing the arguments via the stack or in registers.


Can you cite anything in the C standard that says this is allowed? As I
understand it, you must pass a function precisely the types it expects, or
use a prototype to force the compiler to cast them. Either way, the exact
type must be known where the call is compiled.

DS


__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majordomo@openssl.org


__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majordomo@openssl.org