An object may be the type of its last cast -- but it also can't exactly lose the benefit/cost of being cast to a pointer to an undefined type. As soon as you undefine the type of a pointer, it loses the remnant of ever having had the initial type in the first place.
In K&R C, you couldn't cast to void *, that was first introduced in C89. You had to cast to char *, and then you could cast to some other type in order to make your array indexes jump sizeof(type), essentially (on 8-bit byte machines) referencing &array[(index)*(sizeof(type))]. On 11/10/06, David Schwartz <[EMAIL PROTECTED]> wrote:
> The equivalent of the offending line would be > > foo((double *)(void *) &j); > > since any access through a void pointer CAN change the value. '(double *)(void *)' does not keep some sort of remnant of the 'void *'. The final cast renders the end-result a 'double *' and negates the 'void *'. You cannot cast 'through' another type to get some remnant of that type. (In old C.)
(double *)(void *) can't keep any sort of remnant of the int, as it becomes never-was-an-int-at-all via the (void *) cast. It's also illegal to take the address of a register, which destroys the entire concept of aliasing in the first place -- core has always been core, and any operation can be performed on any part of core (with the proviso that the machine code generated by the C compiler must assure proper alignment for the processor). Trying to treat any piece of core as anything other than a union of all possible types (since it can't be a struct, because structs take up more memory to be able to do what they do, and that violates the assumptions on which the string library depends, among others) is completely foolhardy, and gives rise to a situation which would more properly be in the domain of 'pedantic'.
> Thank you for showing me why I should always include > -fno-strict-aliasing in my gcc commandlines. It's broken, horribly. Actually, what's broken is not allowing a large class of useful optimizations for the occasional code that chooses to invoke undefined behavior. That said, I do exactly what you suggest. I've had too much old code break horribly and subtly to find the optimizations worth the risk. So my 'official' position is not the same as my personal position.
'occasional'? I've never examined any substantial program in C that doesn't invoke that -- even if just to be able to read data from disk into memory.
C has unions and 'char *', and more recently 'void *'. However, you cannot invoke them and then discard them and expect some 'remnant'. An object is the type of the last cast. I'm going to go dig out my standard. Maybe I'm misremembering. DS
An object is the type of the last cast -- but if it's ever cast to void *, it must be treated as if it were never any type before that. This may have changed in C99, but I'd really much rather have the option of selecting which dialect I'm using, if only because code that does work will suddenly not work if compiled with a new dialect. (Is the word 'father' or 'goat'? I can't tell...) -Kyle H ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]