On Mar 18, 2016 11:12 PM, "James K. Lowden" <jklowden at schemamania.org>
wrote:
>
> On Fri, 18 Mar 2016 16:33:56 -0600
> Scott Robison <scott at casaderobison.com> wrote:
>
> > I'd rather have code that might use some "undefined behavior" and
> > generates the right answer than code that always conformed to defined
> > behavior yet was logically flawed.
>
> Code that falls under undefined behavior *is* logically flawed, by
> definition.  Whether or not it works, it's not specified to.  The
> compiler may have generated perfectly correct machine code, but another
> compiler or some future version of your present compiler may not.

Perhaps I should have said "undefined behavior as per the standard". Code
that does what is intended for the intended target environment utilizing a
specific tool chain is not logically flawed just because the standard calls
a construct "undefined behavior".

> You might share my beef with the compiler writers, though: lots things
> that are left undefined shouldn't be.

Not just compiler writers but standards organizations. Lots of overlap to
be sure, but not 100%.

Because hardware architecture
> varies, some practices that do work and have worked and are expected to
> work on a wide variety of machines are UB.  A recent thread on using
> void* for a function pointer is an example: dlsym(2) returns a function
> pointer defined as void*, but the C standard says void* can only refer
> to data, not functions!

So I guess casting between function pointers might be arguably safer if the
void* form of a function was called void(*)(void) though even then there
can be multiple forms of function pointers (like near vs far pointers in
x86 real mode).

>
> Machines exist for which the size of a function pointer is not
> sizeof(void*).  Source code that assumes they are the same size is not
> portable to those architectures.  Fine.  But a particular compiler
> generates code for a particular architecture.  On x86 hardware, all
> pointers have always been and will always be the same size.  All
> Linux/Posix code relies on that, too, along with a host of other
> assumptions. If that ever changed, a boat load of code would have to be
> changed.  Why does the compiler writer feel it's in his interest or
> mine to warn me about that not-happening eventuality?  For the machine
> I'm compilng for, the code is *not* in error.  For some future machine,
> maybe it will be; let's leave that until then.
>
> I was looking at John Regehr's blog the other day.  I think it was
> there that I learned that the practice of dropping UB code on the floor
> has been going on longer than I'd realized; it's just that gcc has been
> more aggressive in recent years.  I think it was there I saw this
> construction:
>
>         if( p < p + n)
>                 error
>
> where p is a pointer.  On lots of architectures, for large n, p + n can
> be negative.  The test works.  Or did.  The C standard says that's
> UB, though. It doesn't promise the pointer will go negative.  It doesn't
> promise it won't.  It doesn't promise not to tell your mother about
> it.  And, in one recent version, it doesn't compile it.  Warning?  No.
> Error? No.  Machine code?  No!  It's UB, so no code is generated (ergo,
> no error handling)!  Even though the hardware instructions that would
> be -- that used to be -- generated work as implied by the code.

Yes, these are the sorts of things that are frustrating.

> Postel's Law is to be liberal in what you accept and conservative in
> what you emit.  The compilers have been practicing the opposite,
> thwarting common longstanding practice just because they "can".
>
> Dan Bernstein is calling for a new C compiler that is 100%
> deterministic: no UB.  All UB per the standard would be defined by the
> compiler.  And maybe a few goodies, like zero-initialized automatic
> (stack) variables.

Neat idea, though undefined behavior isn't always bad. Interesting article
at http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
that goes into some considerations.

>
> Such a compiler would enjoy great popularity, even if it imposed, say,
> a 5% performance penalty, because C programmers would have greater
> confidence in their code working as expected. They'd have some
> assurance that the compiler wouldn't cut them off at the knees in its
> next release.  As he says, there's not real choice between fast and
> correct

Except that testing can verify something is correct for a given environment.

  If the "always defined befavior" compiler got off the ground,
> may it would finally drive gcc & friends in the direction of working
> with their users for a change.  Or make them irrelevant.

I think they'd continue to be popular with people looking to eek out as
much performance as possible.

Reply via email to