emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Emacs-diffs] trunk r114593: * lisp.h (eassert): Don't use 'assume'.


From: Daniel Colascione
Subject: Re: [Emacs-diffs] trunk r114593: * lisp.h (eassert): Don't use 'assume'.
Date: Fri, 11 Oct 2013 08:57:59 -0700
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Thunderbird/24.0

On 10/11/13 4:19 AM, Eli Zaretskii wrote:
Date: Fri, 11 Oct 2013 02:55:44 -0700
From: Daniel Colascione <address@hidden>
CC: address@hidden, address@hidden

While the programmer may have written her C code under the assumption
that an asserted condition holds, the compiler can't know that the
asserted condition holds when generating its machine code. The point of
the assume mechanism is to provide this information to the compiler.

The compiler will be unable to take advantage of that information,
because there's no source code to apply that information to.

I don't understand this argument. In my example, the assume would inform
the compiler that it didn't have to emit code to handle division in the
case that *b is zero.

I think Stephen explained this already.

No, he didn't, and neither did you.

In most cases, you won't see any code that can be optimized
out using this assumption, as the programmer already did that --
that's why she added the assertion in the first place.

At the C level, not the code generation level.

Code is generated from the C code, not out of thin air.

And we're talking about giving the compiler more information about the C
code.

Information about C code that just isn't there will not help the
compiler.

We're asserting things about symbols that appear textually in nearby code. That's the information we're providing. Claiming that we're not providing information about real code is nonsense. You can't manually perform all the transformations the compiler itself might. You can perform some, but not all, optimization manually.

If the programmer really expects an assertion not to hold, he can
use a variant that doesn't assume the condition holds. But these
cases should be rare.

You are wrong: in Emacs, these cases are the vast majority.  Just take
a look at the code which uses assertions.

No, I don't think those cases are the majority. I can compile Emacs --enable-checking, then run it without seeing it insantly crash and burn. That I can do so means these assertions are asserting things that are actually true. The idea that we're putting into assert conditions that might not be true is very strange. If a condition really might not be true, the right thing is to signal an error or abort Emacs, not write eassert.

The problem is to make sure an assertion obviously _is_ free of side
effects.  With Emacs's massive use of macros, which call other macros,
which call other macros, which... -- that is extremely hard.  And why
should a programmer who just wants to assert something go to such
great lengths?  That is just a maintenance burden for which I find no
good justification.

What great lengths? Most common macros --- things like EQ --- are
clearly free of side effects.

There are a lot of macros much more complex than EQ.

So don't use the assume-and-assert macros for questionable cases.

People tend to forget subtle and obscure factoids.  The risk of any
one of us to forget and just treat this macro as a function call is
real.  See bug #15565 as a clear example.

Bug 15565 was caused by changing the semantics of existing calls to eassert. This bug forms a poor argument against having a different macro that asserts and assumes.

The more exotic assertions probably aren't worth assuming anyway.

Not sure I understand what you are saying here.

I'm speculating that the optimization value to be gained from assuming
very complex conditions is smaller than the value gained for assuming
relatively simple conditions.

But if assume-and-assert macro exists, this abuse is exactly what is
going to happen.

I can see changing eassert to eassume being problematic. I don't buy at all the idea that somehow _having_ an assert-and-assume macro is dangerous, especially if you document that this macro might evaluate its argument even in assertion-disabled builds. It has a different name and acts differently. That's what names are for, to distinguish behaviors.

But I'm clearly not winning this one. I think that 1) having a different macro with different semantics is actually perfectly safe and maintainable, and that 2) measurable (if minor) improvements in code generation warrant changing some assertions to use this different macro instead of eassert. But if others disagree this strongly, let's take out the feature until we can show a specific case where it makes a bigger difference.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]