RFH: aliasing problems
Steven Johnson
sjohnson at sakuraindustries.com
Wed Dec 13 03:28:11 UTC 2006
Sergei Organov wrote:
> Steven Johnson writes:
> [...]
>
>> Here is concrete help:
>>
>> if_ethersubr.c
>>
>> Line 598, 692
>> sin = (struct sockaddr_in *)&(ifr->ifr_addr);
>>
>> change it to
>> sin = (struct sockaddr_in *)(void*)&(ifr->ifr_addr);
>>
>> Line 881:
>> sa = (struct sockaddr *) & ifr->ifr_data;
>> to
>> sa = (struct sockaddr *)(void*) & ifr->ifr_data;
>>
>> Why, because C99 says you can turn any pointer to a void* and any void*
>> to any other pointer. This will silence the warning.
>>
>
> That's exactly what one should never do. Silence compiler warnings by
> yet another trick will bite us later. Aliasing rules start to play when
> you *access* actual object by dereferencing the pointer, so any
> intermediate pointer conversions don't change anything.
>
>
In principle this is no different to the changes that Joel suggested for
the Thread Ready Chain corruption.
The fact remains, that the warning does not tell you that there is a
problem that will cause broken code, and won't always tell you when the
code is broken, such as in my example.
Also, I do not see any way to fix this code otherwise. The common
suggestion of "use a union" instead of this type of "sub typing by
pointer casting" is actually not permissible.
See:
http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_028.html
The relevant part from the defect report is:
"""
Subclause 6.3.2.3, page 42, lines 5-6:
... if a member of a union object is accessed after a value has been
stored in a different member of the object, the behaviour is
implementation-defined.
Therefore, an alias is not permitted and the optimization is allowed.
"""
As there is no guarantee about the overlap of members of unions (except
for common starting members). You can not safely type pun (for example)
a long to a float using a union, because the compiler is free to assume
they do not overlap. Same goes for structures in a union. So while you
may get away with type punning through unions it isn't portable, and
isn't safe from a future optimisation.
So I don't see how to "fix" the networking code in any other way than
silencing the warning, and ensuring no "constant propogation" can be
performed. I did not see any places where I thought constant
propagation could be performed in any of this code.
> After your "fix", you continue to access the object, say, ifr->ifr_data,
> through incompatible pointer of type "struct sockaddr*". To fix this,
> you either need to change type of ifr->ifr_data, or type of the pointer
> you access the object by. Converting pointers back and forth doesn't
> change anything but make poor compiler crazy to the level it stops warn
> you where it should.
>
>
>> In this case there is no possibility for common sub expression
>> elimination as there is no manipulation of pointer data between the
>> setting of this value and its use that could trigger the optimisation,
>> and it be working from a previous state, and not a undetected updated
>> state, and so the warning is completely bogus.
>>
>
> What common sub-expression elimination has to do with aliasing rules?
> The answer is: nothing.
>
Ok, sorry, I meant "constant propagation". My bad.
> Steven, it seems you still miss the meaning of aliasing rules, so all the
> suggestions you give are just tricks to silence compiler warnings, not
> actual fixes to the problems.
>
Please enlighten me as to the meaning of the aliasing rules, in a way
that makes sense given the other parts of the specification with regard
to permissible pointer conversion. I would be overjoyed to be
enlightened on this matter.
Steven J
More information about the users
mailing list