something to warry about...

Denys Vlasenko vda.linux at googlemail.com
Wed Jan 19 13:48:26 UTC 2011


On Wed, Jan 19, 2011 at 1:20 PM, Johannes Stezenbach <js at sig21.net> wrote:
>> >  static smallint detect_link_mii(void)
>> >  {
>> > -       struct ifreq ifreq;
>> > -       struct mii_ioctl_data *mii = (void *)&ifreq.ifr_data;
>> > +       union mii_ifreq mii_ifreq;
>> > +       union mii_ifreq *mii = (void *)&mii_ifreq.ifreq.ifr_data;
>>
>> Here you again assign void** to union mii_ifreq* -
>> types still do not match.
>
> That's why I suggested to replace ifr_data with ifr_ifru,
> which is less confusing but the result is the same.

No, it should not be changed.

We do not write for compiler. We write for *humans*
to read our code.

ifr_data isn't called "data" for no reason. It means
"a generic data field", and here we use it exactly
for that purpose.

Whereas ifr_ifru means "ifr union" and is only
an implementation detail of the  struct ifreq,
not meant to be used directly.
Had C supported unnamed members like C++ does,
struct ifreq would have that member union without name.


>> This doesn't emit warnings probably because gcc
>> takes a brute-force approach to handling unions
>> by marking every pointer derived from any union member
>> "potentially aliases anything". Future versions of gcc
>> may become "more clever" again, and warnings will return.
>
> I disagree.  C99 aliasing rules say two pointers of the
> same type can alias.  Consider the follwing:
>
>        void *p = malloc(1000);
>        union mii_ifreq *m1 = p;
>        union mii_ifreq *m2 = p + 8;
>
> m1 and m2 can alias, and this does not change if you
> change the line to
>
>        union mii_ifreq *m2 = (void *)&m1->ifreq.ifr_ifru;

>> > +       union mii_ifreq mii_ifreq;
>> > +       union mii_ifreq *mii = (void *)&mii_ifreq.ifreq.ifr_data;

In your patch, the pointers have an offset relative each other:
even if compiler will assume they are aliased, aliasing means
mii_ifreq.foo and mii->foo need to be considered as possibly the same.
But in your case, mii_ifreq.foo doesn't map to mii->foo,
it maps to mii->bar!

But I have a deeper problem here. I do not see it as a good decision
to butcher a readable piece of code into a obfuscated mess *only*
to shut up gcc. gcc has to provide means to do it in some cleaner way.

-- 
vda


More information about the busybox mailing list