(no subject)

Joel Rees joel.rees at gmail.com
Mon Jul 20 02:15:18 UTC 2009


(Apologies for messing up the threading yet one more time, and for  
cluttering up the fedora thread with more stuff that is only semi- 
relevant here.)

Michael Eager wrote,

> ...
> Compilers determine what modifications they can make to the code using
> the inferences they make based on the data flow through a program.   
> They
> don't say "well, this is undefined, we can muck it up however we  
> like".
>
> In the case of this *kernel* bug, the compiler determined that the  
> pointer
> must be valid, because it had been previously dereferenced.

Would it be entirely inappropriate to have a compiler switch that  
would cause the compiler to issue warnings when pointers are used  
without testing after being returned from functions calls?

> This allowed
> the compiler to eliminate a test which would always be false, *as long
> as the behavior of the previous code was defined*.

Which is a problem, because the compiler authors are fully aware that  
dereferencing a pointer without testing is a common bug.

> This code is correct and well defined as long as the pointer is valid.

Only if you can assume that the dereference after the function call  
and before any comparison must indicate that the programer knows the  
function will always return a valid pointer. Otherwise, the code, as  
it was, was not well defined.

> The behavior only becomes undefined when the pointer is null.  The  
> only
> way that the compiler could determine that the initial dereference of
> the pointer was undefined would be to insert a test for null before  
> the
> dereference.

That would be non-standard behavior, and potentially incorrect. And,  
if it could solve the problem, it would indicate that the dereference  
before testing could, and should have been flagged with a warning.

> It would have to do this for every piece of code which
> dereferenced a pointer which was passed into a function, dramatically
> impacting performance.  Or perhaps it could issue a warning message
> saying that it couldn't determine that the pointer was valid,  
> resulting
> in a warning that would occur thousands of times when compiling the
> kernel.

If this kind of code really occurs that often in the kernel, we have  
serious problems.

> OK, what would reasonable, sane people do in that case? That's right,
> they'd fall back on the behavior of just doing what the program source
> code says, but no, gcc is too smart for that, gcc's undefined behavior
> shows how smart it is and therefore makes much more sense than
> doing the obvious :-).
>
> You can get exactly that behavior by not optimizing your code.
> Your code will run much slower, but that's OK, isn't it?
>
> Ah, you want optimizations?  But you want them to magically decide  
> that
> one is an error in the program and shouldn't be done, while in another
> place the same optimization should be done because it generates better
> code.  OK, write a description of how to determine one case from the
> other and I'm sure every compiler developer will rush to implement it.


Actually, it's fairly simple. The default warning option for  
discarding code should be to issue a warning about discarded code.  
Discarded code generally indicates that the programmer did not say  
what he meant, and that is usually a no-no in kernels.

And, IMNSHO, in any other application, the programer should be  
required to insist that discarded code can safely be ignored, via  
pragma or switch.

Yeah, this sort of debate would be more appropriate in the compiler  
developers' mailing list. I feel like letting a little steam off, and  
I don't feel like signing up for yet another mailing list. So sue me.




More information about the fedora-list mailing list