On 01/10/2010 10:30 AM, Andreas Schwab wrote:
> Dave Korn <[email protected]> writes:
>
>> Is that really right? The type of the pointer (in6->__s6_addr) that we're
>> casting is unsigned char *, so shouldn't it already alias everything anyway
>> and dereferencing it be allowed, like it is for the casted (a)? I'll file a
>> PR if so. (I can't pretend I find the language in the spec easy to follow.)
>
> IIUC both accesses are actually wrong, but in the case of a there is no
> information about the actual target type, so the compiler cannot
> optimize. In both cases an object is accessed as type uint32_t, but the
> effective type is different.
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
struct in6_addr
{
uint8_t __s6_addr[16];
};
static inline int
address_in_use (unsigned char *a, struct in6_addr *in6)
{
if ((((const uint32_t *)(a))[0]
== ((const uint32_t *)(in6->__s6_addr))[0]
&& ((const uint32_t *)(a))[1]
== ((const uint32_t *)(in6->__s6_addr))[1]
&& ((const uint32_t *)(a))[2]
== ((const uint32_t *)(in6->__s6_addr))[2]
&& ((const uint32_t *)(a))[3]
== ((const uint32_t *)(in6->__s6_addr))[3]))
return 1;
return 0;
}
Why do you say the effective type is different? As long as uint8_t is
a character type and both *a and *in6->__s6_addr have been written as
uint32_t, this looks legal.
Andrew.