unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Eli Zaretskii <eliz@gnu.org>
To: Paul Eggert <eggert@cs.ucla.edu>
Cc: emacs-devel@gnu.org
Subject: Re: FACE_FROM_ID vs FACE_OPT_FROM_ID
Date: Fri, 24 Jun 2016 16:43:05 +0300	[thread overview]
Message-ID: <83twgi1z4m.fsf@gnu.org> (raw)
In-Reply-To: <576D16D3.2000801@cs.ucla.edu> (message from Paul Eggert on Fri,  24 Jun 2016 13:17:39 +0200)

> Cc: emacs-devel@gnu.org
> From: Paul Eggert <eggert@cs.ucla.edu>
> Date: Fri, 24 Jun 2016 13:17:39 +0200
> 
> On 06/24/2016 12:00 PM, Eli Zaretskii wrote:
> >> my reading of this:
> >>
> >> #ifndef ENABLE_CHECKING
> >> # define eassert(cond) ((void) (false && (cond))) /* Check COND compiles.  */
> >>
> >> is that when ENABLE_CHECKING is not defined, eassert does nothing
> >> useful.
> 
> Yes, of course.  eassert (X) should appear only in places where X must 
> be true, i.e., where Emacs is seriously broken if X is false. That's the 
> standard meaning for assertions.

And that is what happens here: if the face ID is not in the face
cache, something is broken, and we cannot continue using that face ID.

In the ENABLE_CHECKING case, we abort immediately, since that's the
meaning of ENABLE_CHECKING: allow early detection of invalid data.
When ENABLE_CHECKING is not defined, which is what happens by default
in Emacs builds, we attempt to "do the best we can without crashing",
thus my suggestion to use the default face, if that is in the cache.
If even that is not in the cache, we cannot display anything, so I
suggest we abort.

If you find the code I proposed after eassert confusing, then we can
condition it on ENABLE_CHECKING being not defined.

Otherwise, I think my suggestion is better than what we have now,
because the current code, when compiled without ENABLE_CHECKING, will
attempt to use invalid face IDs.

> Another way to put it is that in general the behavior of eassert (X) is 
> undefined if X is false.When (defined ENABLE_CHECKING && 
> !suppress_checking), this undefined behavior happens to be a diagnostic 
> and core dump. Otherwise the undefined behavior is whatever the 
> underlying system does afterwards; when (!defined ENABLE_CHECKING) this 
> yields better performance overall in the usual and expected case where 
> Emacs is working properly.

My suggestion was an attempt to make the undefined behavior safer, as
much as it's possible.  That is in line with the general practice in
Emacs: to avoid crashing as much as possible, leaving the user in
charge, so she could shut down the session in an orderly fashion, thus
minimizing the risk of losing precious work.

> It is not necessary to put eassert (X) every place where an expression X 
> must be true. It's helpful only when we reasonably suspect there might 
> be a bug in Emacs, and where platforms typically will not immediately 
> fail for other reasons when X is false. So, before a pointer dereference 
> *P it's not necessary to do eassert (P != NULL) since typical platforms 
> immediately dump core when dereferencing a null pointer anyway. 

That accurately describes the FACE_FROM_ID macro we had before these
changes, and the way we used it.  We could keep that code, but you say
the GCC warning about that is useful, so I suggested a way of avoiding
the warning that also makes our code safer.  After all, if the warning
is useful, we should indeed make changes that improve our code, not
just shut up the warning.

> Conversely, before a subscript operation A[I] it can be helpful to 
> eassert (0 <= I && I < N), since typical platforms lack reliable 
> subscript checking.

And that's exactly what is missing from current uses of FACE_FROM_ID,
when ENABLE_CHECKING is not defined.

So, turning back to my suggestion, do you still object to it?



  reply	other threads:[~2016-06-24 13:43 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-23 20:03 FACE_FROM_ID vs FACE_OPT_FROM_ID Eli Zaretskii
2016-06-24  0:23 ` Paul Eggert
2016-06-24  8:49   ` Eli Zaretskii
2016-06-24  9:27     ` Paul Eggert
2016-06-24  9:57       ` Eli Zaretskii
2016-06-24 10:00       ` Eli Zaretskii
2016-06-24 11:17         ` Paul Eggert
2016-06-24 13:43           ` Eli Zaretskii [this message]
2016-06-24 21:34             ` Paul Eggert
2016-06-25  7:48               ` Eli Zaretskii
2016-06-25 21:34                 ` Paul Eggert
2016-07-02  9:50                   ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=83twgi1z4m.fsf@gnu.org \
    --to=eliz@gnu.org \
    --cc=eggert@cs.ucla.edu \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).