On 11/9/06, David Schwartz wrote:
>
> > Once K&R is included, the situation becomes a lot less clear. Also, as I
> > read the thread on the GCC list, it looks like the situation is further
> > complicated by their desire to avoid an internal compiler error.
> > Also**2,
> > I don't know what you mean by C's aliasing rules; to me that brings to
> > mind the ill-conceived 'noalias' qualifier.
> >
> > If this is worth further discussion, a concrete example (code fragment)
> > would help me a lot.
> >
> > /r$

>
> What I mean by aliasing rules is that with only a few exceptions, a compiler
> is allowed to assume that an access through a pointer of one type cannot
> affect the value of a variable of a different type.
>
> GCC's optimization in this area has gotten to the point where it bites a lot
> of people, and I think it's the aliasing issue that's the problem for
> OpenSSL, not really the function prototype issue. Right now, the GCC bug
> with the most duplicates is due to aliasing errors.
>
> The GCC "not a bug" page gives this example:
>
> int main()
> {
> short a[2];
>
> a[0]=0x1111;
> a[1]=0x1111;
>
> *(int *)a = 0x22222222; /* violation of aliasing rules */
>
> printf("%x %x\n", a[0], a[1]);
> return 0;
> }
>
> The compiler has every right to print 1111 and 1111, because under C rules,
> no modification to an integer can change the value of a short.


Ummm... could you please cite where in the standard (and which
standard within which) you're seeing that? That is completely
opposite of how every compiler I've ever used, across seven OSes and
five platforms, has acted -- and I would argue that it makes no sense.
Any memory location (pointer) can be seen as different things,
depending on the cast that is used. If you're worried, you can look
at the *(int a) = 0x22222222 as creating a "const" qualifier, but even
then the issue becomes murky -- if the pointer is cast to (void *) and
passed to another function, then the called function has no idea what
to look at it as without extra context, which could be wildly
inaccurate. ("cast drops const qualifier" is a warning, not an
error.)

> However, this is also an example:
>
> extern void foo();
> int main(void)
> {
> int j=2;
> foo((double *) &j);
> printf("%d\n", j);
> return 0;
> }
>
> The compiler has every right to assume that 'j' still has the value '2' in
> the 'printf' call because 'j' is local to 'main' and no modification through
> a 'double *' pointer can possibly change the value of an 'int'.


A pointer to an address in memory should much more effectively and
efficiently be viewed as a union of all possible types, including void
* (which, by its definition, must be cast to another type before it
can be accessed).

The equivalent of the offending line would be

foo((double *)(void *) &j);

since any access through a void pointer CAN change the value.

Thank you for showing me why I should always include
-fno-strict-aliasing in my gcc commandlines. It's broken, horribly.

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