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