unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
@ 2011-04-29  8:08 Paul Eggert
  2011-04-29  8:49 ` Eli Zaretskii
  2011-04-29  8:56 ` support " Paul Eggert
  0 siblings, 2 replies; 19+ messages in thread
From: Paul Eggert @ 2011-04-29  8:08 UTC (permalink / raw)
  To: Emacs Development

Currently, the Emacs C-language code assumes that EMACS_INT and
pointers have the same width.  This is true of current ports, but I'd
like to create a 32-bit port with 64-bit EMACS_INT, so that Emacs is
not arbitrarily restricted by its small integer range when editing
large files on 32-bit hosts.  I'll call this a "32+64-bit port".

The first step is some bookkeeping changes, to remove assumptions in a
few parts of Emacs that EMACS_INT and pointers have the same width.
Here's a draft patch to do this bookkeeping.  This patch should have
almost no effect on existing Emacs ports, because it doesn't change
the width of EMACS_INT: it merely takes a bit more care in specifying
types.

The main change in this patch is to introduce the types EMACS_INTPTR
and EMACS_UINTPTR, which are like EMACS_INT and EMACS_UINT but are
defined to be just wide enough to represent a pointer.  On current
ports there is no difference between EMACS_INT and EMACS_INTPTR, but
on a 32+64-bit port, EMACS_INTPTR will be 32 bits and EMACS_INT will
be 64 bits.  Without this distinction, gcc would too often complain
about casting between pointers and integers of different widths.

The patch also removes a couple of hardwired word size assumptions in
random number and hashing functions.

This patch may affect the Windows build in a minor way, because it
includes <inttypes.h>.  If there is no <inttypes.h> on Windows, an
empty inttypes.h should work as a substitute.  <inttypes.h> should not
be a problem on non-Microsoft platforms, since 'configure' and 'make'
already supply a replacement <inttypes.h> on older platforms that lack
it.

Step 2 will change EMACS_INT to be 64 bits on 32+64-bit ports.
That is a bigger deal, and I'll send a later email about it.

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: eggert@cs.ucla.edu-20110429075557-r9wqpc93fj6d7uui
# target_branch: bzr+ssh://eggert@bzr.savannah.gnu.org/emacs/trunk
# testament_sha1: 817842d95fd8b067f0edd2296d9b089c83f8cb96
# timestamp: 2011-04-29 00:56:54 -0700
# base_revision_id: eggert@cs.ucla.edu-20110428220600-5zhklv5yx5uycht7
# 
# Begin patch
=== modified file 'ChangeLog'
--- ChangeLog	2011-04-27 02:17:44 +0000
+++ ChangeLog	2011-04-29 07:55:57 +0000
@@ -1,3 +1,7 @@
+2011-04-29  Paul Eggert  <eggert@cs.ucla.edu>
+
+	* configure.in (BITS_PER_LONG_LONG): New macro.
+
 2011-04-27  Ben Key  <bkey76@gmail.com>
 
 	* configure.in: Fixed a bug that caused configure with

=== modified file 'configure.in'
--- configure.in	2011-04-27 02:17:44 +0000
+++ configure.in	2011-04-29 07:55:57 +0000
@@ -3518,7 +3518,8 @@
 #endif
 
 /* These default definitions are good for almost all machines.
-   The exceptions override them in m/MACHINE.h.  */
+   Any exceptions should override them in m/MACHINE.h.
+   They must be usable in preprocessor conditionals.  */
 
 #ifndef BITS_PER_CHAR
 #define BITS_PER_CHAR 8
@@ -3528,9 +3529,6 @@
 #define BITS_PER_SHORT 16
 #endif
 
-/* Note that lisp.h uses this in a preprocessor conditional, so it
-   would not work to use sizeof.  That being so, we do all of them
-   without sizeof, for uniformity's sake.  */
 #ifndef BITS_PER_INT
 #define BITS_PER_INT 32
 #endif
@@ -3543,6 +3541,10 @@
 #endif
 #endif
 
+#if !defined BITS_PER_LONG_LONG && HAVE_LONG_LONG_INT
+#define BITS_PER_LONG_LONG 64
+#endif
+
 /* Define if the compiler supports function prototypes.  It may do so but
    not define __STDC__ (e.g. DEC C by default) or may define it as zero.  */
 #undef PROTOTYPES

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2011-04-28 20:11:17 +0000
+++ src/ChangeLog	2011-04-29 07:55:25 +0000
@@ -1,3 +1,62 @@
+2011-04-29  Paul Eggert  <eggert@cs.ucla.edu>
+
+	* lread.c, process.c: Do not include <inttypes.h>; lisp.h does it now.
+
+	Prefer intptr_t/uintptr_t for integers the same widths as pointers.
+	This removes an assumption that EMACS_INT and long are the same
+	width as pointers.  The assumption is true for Emacs porting targets
+	now, but we want to make other targets possible.
+	* lisp.h: Include <inttypes.h>, for INTPTR_MAX, UINTPTR_MAX.
+	(EMACS_INTPTR, EMACS_UINTPTR): New macros.
+	In the rest of the code, change types of integers that hold casted
+	pointers to EMACS_INTPTR and EMACS_UINTPTR, systematically
+	replacing EMACS_INT, long, EMACS_UINT, and unsigned long.
+	(XTYPE): Don't cast arg to EMACS_UINT; normally is not needed.
+	(XSET): Cast type of XTYPE arg to EMACS_INTPTR; it is needed here.
+	No need to cast type when ORing.
+	(XPNTR): Return a value of type EMACS_INTPTR or EMACS_UINTPTR.
+	* alloc.c (lisp_align_malloc): Remove a no-longer-needed cast.
+	* doc.c (store_function_docstring): Use EMACS_INTPTR, so as not to
+	assume EMACS_INT is the same width as char *.
+	* gtkutil.c (xg_gtk_scroll_destroy, xg_tool_bar_button_cb):
+	(xg_tool_bar_callback, xg_tool_bar_help_callback, xg_make_tool_item):
+	Remove no-longer-needed casts.
+	(xg_create_scroll_bar, xg_tool_bar_button_cb, xg_tool_bar_callback):
+	(xg_tool_bar_help_callback, xg_make_tool_item):
+	Use EMACS_INTPTR to hold an integer
+	that will be cast to void *; this can avoid a GCC warning
+	if EMACS_INT is not the same width as void *.
+	* menu.c (find_and_call_menu_selection): Remove no-longer-needed cast.
+	* xdisp.c (display_echo_area_1, resize_mini_window_1):
+	(current_message_1, set_message_1):
+	Use a local to convert to proper width without a cast.
+	* xmenu.c (dialog_selection_callback): Likewise.
+
+2011-04-28  Paul Eggert  <eggert@cs.ucla.edu>
+
+	* sysdep.c (get_random): Don't assume EMACS_INT is no wider than long.
+	Also, don't assume VALBITS / RAND_BITS is less than 5,
+	and don't rely on undefined behavior when shifting a 1 left into
+	the sign bit.
+	* lisp.h (get_random): Change signature to match.
+
+	* lread.c (hash_string): Use size_t, not int, for hash computation.
+	Normally we prefer signed values; but hashing is special, because
+	it's better to use unsigned division on hash table sizes so that
+	the remainder is nonnegative.  Also, size_t is the natural width
+	for hashing into memory.  The previous code used 'int', which doesn't
+	retain enough info to hash well into very large tables.
+	(oblookup, oblookup_last_bucket_number, Funintern): Likewise.
+
+	* dbusbind.c: Don't possibly lose pointer info when converting.
+	(xd_remove_watch, Fdbus_init_bus, xd_read_queued_messages):
+	Use XPNTR rather than XHASH, so that the high-order bits of
+	the pointer aren't lost when converting through void *.
+
+	* eval.c (Fautoload): Don't double-shift a pointer.
+
+	* fns.c (Frandom): Let EMACS_UINT be wider than unsigned long.
+
 2011-04-28  Paul Eggert  <eggert@cs.ucla.edu>
 
 	* doprnt.c (doprnt): Omit useless test; int overflow check (Bug#8545).

=== modified file 'src/alloc.c'
--- src/alloc.c	2011-04-26 06:17:52 +0000
+++ src/alloc.c	2011-04-29 07:54:43 +0000
@@ -438,7 +438,7 @@
    ALIGNMENT must be a power of 2.  */
 
 #define ALIGN(ptr, ALIGNMENT) \
-  ((POINTER_TYPE *) ((((EMACS_UINT)(ptr)) + (ALIGNMENT) - 1) \
+  ((POINTER_TYPE *) ((((EMACS_UINTPTR) (ptr)) + (ALIGNMENT) - 1) \
 		     & ~((ALIGNMENT) - 1)))
 
 
@@ -876,7 +876,7 @@
 #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING)
 
 #define ABLOCK_ABASE(block) \
-  (((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE)   \
+  (((EMACS_UINTPTR) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE)	\
    ? (struct ablocks *)(block)					\
    : (block)->abase)
 
@@ -888,7 +888,7 @@
 #define ABLOCKS_BASE(abase) (abase)
 #else
 #define ABLOCKS_BASE(abase) \
-  (1 & (long) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1])
+  (1 & (EMACS_INTPTR) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1])
 #endif
 
 /* The list of free ablock.   */
@@ -914,7 +914,7 @@
   if (!free_ablock)
     {
       int i;
-      EMACS_INT aligned; /* int gets warning casting to 64-bit pointer.  */
+      EMACS_INTPTR aligned; /* int gets warning casting to 64-bit pointer.  */
 
 #ifdef DOUG_LEA_MALLOC
       /* Prevent mmap'ing the chunk.  Lisp data may not be mmap'ed
@@ -977,17 +977,18 @@
 	  abase->blocks[i].x.next_free = free_ablock;
 	  free_ablock = &abase->blocks[i];
 	}
-      ABLOCKS_BUSY (abase) = (struct ablocks *) (long) aligned;
+      ABLOCKS_BUSY (abase) = (struct ablocks *) aligned;
 
-      eassert (0 == ((EMACS_UINT)abase) % BLOCK_ALIGN);
+      eassert (0 == ((EMACS_UINTPTR) abase) % BLOCK_ALIGN);
       eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */
       eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase);
       eassert (ABLOCKS_BASE (abase) == base);
-      eassert (aligned == (long) ABLOCKS_BUSY (abase));
+      eassert (aligned == (EMACS_INTPTR) ABLOCKS_BUSY (abase));
     }
 
   abase = ABLOCK_ABASE (free_ablock);
-  ABLOCKS_BUSY (abase) = (struct ablocks *) (2 + (long) ABLOCKS_BUSY (abase));
+  ABLOCKS_BUSY (abase) =
+    (struct ablocks *) (2 + (EMACS_INTPTR) ABLOCKS_BUSY (abase));
   val = free_ablock;
   free_ablock = free_ablock->x.next_free;
 
@@ -1000,7 +1001,7 @@
   if (!val && nbytes)
     memory_full ();
 
-  eassert (0 == ((EMACS_UINT)val) % BLOCK_ALIGN);
+  eassert (0 == ((EMACS_UINTPTR) val) % BLOCK_ALIGN);
   return val;
 }
 
@@ -1018,11 +1019,12 @@
   ablock->x.next_free = free_ablock;
   free_ablock = ablock;
   /* Update busy count.  */
-  ABLOCKS_BUSY (abase) = (struct ablocks *) (-2 + (long) ABLOCKS_BUSY (abase));
+  ABLOCKS_BUSY (abase) =
+    (struct ablocks *) (-2 + (EMACS_INTPTR) ABLOCKS_BUSY (abase));
 
-  if (2 > (long) ABLOCKS_BUSY (abase))
+  if (2 > (EMACS_INTPTR) ABLOCKS_BUSY (abase))
     { /* All the blocks are free.  */
-      int i = 0, aligned = (long) ABLOCKS_BUSY (abase);
+      int i = 0, aligned = (EMACS_INTPTR) ABLOCKS_BUSY (abase);
       struct ablock **tem = &free_ablock;
       struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1];
 
@@ -1039,7 +1041,7 @@
       eassert ((aligned & 1) == aligned);
       eassert (i == (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1));
 #ifdef USE_POSIX_MEMALIGN
-      eassert ((unsigned long)ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0);
+      eassert ((EMACS_UINTPTR) ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0);
 #endif
       free (ABLOCKS_BASE (abase));
     }
@@ -1772,7 +1774,7 @@
   s = string_free_list;
   while (s != NULL)
     {
-      if ((unsigned long)s < 1024)
+      if ((EMACS_UINTPTR) s < 1024)
 	abort();
       s = NEXT_FREE_LISP_STRING (s);
     }
@@ -2432,10 +2434,10 @@
   &= ~(1 << ((n) % (sizeof(int) * CHAR_BIT)))
 
 #define FLOAT_BLOCK(fptr) \
-  ((struct float_block *)(((EMACS_UINT)(fptr)) & ~(BLOCK_ALIGN - 1)))
+  ((struct float_block *) (((EMACS_UINTPTR) (fptr)) & ~(BLOCK_ALIGN - 1)))
 
 #define FLOAT_INDEX(fptr) \
-  ((((EMACS_UINT)(fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float))
+  ((((EMACS_UINTPTR) (fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float))
 
 struct float_block
 {
@@ -2544,10 +2546,10 @@
    / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1))
 
 #define CONS_BLOCK(fptr) \
-  ((struct cons_block *)(((EMACS_UINT)(fptr)) & ~(BLOCK_ALIGN - 1)))
+  ((struct cons_block *) ((EMACS_UINTPTR) (fptr) & ~(BLOCK_ALIGN - 1)))
 
 #define CONS_INDEX(fptr) \
-  ((((EMACS_UINT)(fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons))
+  (((EMACS_UINTPTR) (fptr) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons))
 
 struct cons_block
 {
@@ -4021,7 +4023,7 @@
   struct mem_node *m;
 
   /* Quickly rule out some values which can't point to Lisp data.  */
-  if ((EMACS_INT) p %
+  if ((EMACS_INTPTR) p %
 #ifdef USE_LSB_TAG
       8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8.  */
 #else
@@ -6072,7 +6074,7 @@
 {
   Lisp_Object end;
 
-  XSETINT (end, (EMACS_INT) (char *) sbrk (0) / 1024);
+  XSETINT (end, (EMACS_INTPTR) (char *) sbrk (0) / 1024);
 
   return end;
 }

=== modified file 'src/dbusbind.c'
--- src/dbusbind.c	2011-04-19 00:34:42 +0000
+++ src/dbusbind.c	2011-04-28 00:48:19 +0000
@@ -892,7 +892,7 @@
     return;
 
   /* Unset session environment.  */
-  if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
+  if (data != NULL && data == (void *) XPNTR (QCdbus_session_bus))
     {
       XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
       unsetenv ("DBUS_SESSION_BUS_ADDRESS");
@@ -929,7 +929,7 @@
 					    xd_add_watch,
 					    xd_remove_watch,
                                             xd_toggle_watch,
-					    (void*) XHASH (bus), NULL))
+					    (void *) XPNTR (bus), NULL))
     XD_SIGNAL1 (build_string ("Cannot add watch functions"));
 
   /* Add bus to list of registered buses.  */
@@ -1824,7 +1824,7 @@
   if (data != NULL)
     while (!NILP (busp))
       {
-	if (data == (void*) XHASH (CAR_SAFE (busp)))
+	if (data == (void *) XPNTR (CAR_SAFE (busp)))
 	  bus = CAR_SAFE (busp);
 	busp = CDR_SAFE (busp);
       }

=== modified file 'src/doc.c'
--- src/doc.c	2011-04-27 19:05:21 +0000
+++ src/doc.c	2011-04-29 07:54:43 +0000
@@ -349,10 +349,10 @@
 	return Qnil;
       /* FIXME: This is not portable, as it assumes that string
 	 pointers have the top bit clear.  */
-      else if ((EMACS_INT) XSUBR (fun)->doc >= 0)
+      else if ((EMACS_INTPTR) XSUBR (fun)->doc >= 0)
 	doc = build_string (XSUBR (fun)->doc);
       else
-	doc = make_number ((EMACS_INT) XSUBR (fun)->doc);
+	doc = make_number ((EMACS_INTPTR) XSUBR (fun)->doc);
     }
   else if (COMPILEDP (fun))
     {
@@ -506,8 +506,11 @@
   /* The type determines where the docstring is stored.  */
 
   /* Lisp_Subrs have a slot for it.  */
-  if (SUBRP (fun))
-    XSUBR (fun)->doc = (char *) - offset;
+   if (SUBRP (fun))
+     {
+       EMACS_INTPTR negative_offset = - offset;
+       XSUBR (fun)->doc = (char *) negative_offset;
+     }
 
   /* If it's a lisp form, stick it in the form.  */
   else if (CONSP (fun))

=== modified file 'src/eval.c'
--- src/eval.c	2011-04-27 18:15:29 +0000
+++ src/eval.c	2011-04-28 00:45:40 +0000
@@ -2144,7 +2144,7 @@
        We used to use 0 here, but that leads to accidental sharing in
        purecopy's hash-consing, so we use a (hopefully) unique integer
        instead.  */
-    docstring = make_number (XHASH (function));
+    docstring = make_number (XPNTR (function));
   return Ffset (function,
 		Fpurecopy (list5 (Qautoload, file, docstring,
 				  interactive, type)));

=== modified file 'src/fns.c'
--- src/fns.c	2011-04-25 07:14:46 +0000
+++ src/fns.c	2011-04-28 00:43:18 +0000
@@ -75,7 +75,7 @@
 {
   EMACS_INT val;
   Lisp_Object lispy_val;
-  unsigned long denominator;
+  EMACS_UINT denominator;
 
   if (EQ (limit, Qt))
     seed_random (getpid () + time (NULL));
@@ -88,7 +88,7 @@
 	 it's possible to get a quotient larger than n; discarding
 	 these values eliminates the bias that would otherwise appear
 	 when using a large n.  */
-      denominator = ((unsigned long)1 << VALBITS) / XFASTINT (limit);
+      denominator = ((EMACS_UINT) 1 << VALBITS) / XFASTINT (limit);
       do
 	val = get_random () / denominator;
       while (val >= XFASTINT (limit));

=== modified file 'src/gtkutil.c'
--- src/gtkutil.c	2011-04-19 07:10:55 +0000
+++ src/gtkutil.c	2011-04-29 07:54:43 +0000
@@ -3354,7 +3354,7 @@
 static void
 xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data)
 {
-  int id = (int) (EMACS_INT) data; /* The EMACS_INT cast avoids a warning. */
+  int id = (EMACS_INTPTR) data;
   xg_remove_widget_from_map (id);
 }
 
@@ -3375,7 +3375,7 @@
 {
   GtkWidget *wscroll;
   GtkWidget *webox;
-  int scroll_id;
+  EMACS_INTPTR scroll_id;
 #ifdef HAVE_GTK3
   GtkAdjustment *vadj;
 #else
@@ -3397,11 +3397,10 @@
 
   scroll_id = xg_store_widget_in_map (wscroll);
 
-  /* The EMACS_INT cast avoids a warning. */
   g_signal_connect (G_OBJECT (wscroll),
                     "destroy",
                     G_CALLBACK (xg_gtk_scroll_destroy),
-                    (gpointer) (EMACS_INT) scroll_id);
+                    (gpointer) scroll_id);
   g_signal_connect (G_OBJECT (wscroll),
                     "change-value",
                     scroll_callback,
@@ -3663,8 +3662,8 @@
                        GdkEventButton *event,
                        gpointer user_data)
 {
-  /* Casts to avoid warnings when gpointer is 64 bits and int is 32 bits */
-  gpointer ptr = (gpointer) (EMACS_INT) event->state;
+  EMACS_INTPTR state = event->state;
+  gpointer ptr = (gpointer) state;
   g_object_set_data (G_OBJECT (widget), XG_TOOL_BAR_LAST_MODIFIER, ptr);
   return FALSE;
 }
@@ -3678,10 +3677,9 @@
 static void
 xg_tool_bar_callback (GtkWidget *w, gpointer client_data)
 {
-  /* The EMACS_INT cast avoids a warning. */
-  int idx = (int) (EMACS_INT) client_data;
+  EMACS_INTPTR idx = (EMACS_INTPTR) client_data;
   gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER);
-  int mod = (int) (EMACS_INT) gmod;
+  EMACS_INTPTR mod = (EMACS_INTPTR) gmod;
 
   FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
   Lisp_Object key, frame;
@@ -3960,8 +3958,7 @@
                            GdkEventCrossing *event,
                            gpointer client_data)
 {
-  /* The EMACS_INT cast avoids a warning. */
-  int idx = (int) (EMACS_INT) client_data;
+  EMACS_INTPTR idx = (EMACS_INTPTR) client_data;
   FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
   Lisp_Object help, frame;
 
@@ -4155,14 +4152,16 @@
 
   if (wimage)
     {
-      /* The EMACS_INT cast avoids a warning. */
+      EMACS_INTPTR ii = i;
+      gpointer gi = (gpointer) ii;
+
       g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
                         G_CALLBACK (xg_tool_bar_menu_proxy),
-                        (gpointer) (EMACS_INT) i);
+                        gi);
 
       g_signal_connect (G_OBJECT (wb), "clicked",
                         G_CALLBACK (xg_tool_bar_callback),
-                        (gpointer) (EMACS_INT) i);
+                        gi);
 
       g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f);
 
@@ -4193,11 +4192,11 @@
       g_signal_connect (G_OBJECT (weventbox),
                         "enter-notify-event",
                         G_CALLBACK (xg_tool_bar_help_callback),
-                        (gpointer) (EMACS_INT) i);
+                        gi);
       g_signal_connect (G_OBJECT (weventbox),
                         "leave-notify-event",
                         G_CALLBACK (xg_tool_bar_help_callback),
-                        (gpointer) (EMACS_INT) i);
+                        gi);
     }
 
   if (wbutton) *wbutton = wb;

=== modified file 'src/lisp.h'
--- src/lisp.h	2011-04-26 19:14:07 +0000
+++ src/lisp.h	2011-04-29 07:54:43 +0000
@@ -22,6 +22,7 @@
 
 #include <stdarg.h>
 #include <stddef.h>
+#include <inttypes.h>
 
 /* Use the configure flag --enable-checking[=LIST] to enable various
    types of run time checks for Lisp objects.  */
@@ -54,6 +55,18 @@
 #endif
 #endif
 
+/* Integers large enough to hold casted pointers without losing info.  */
+#ifdef INTPTR_MAX
+# define EMACS_INTPTR intptr_t
+#else
+# define EMACS_INTPTR EMACS_INT
+#endif
+#ifdef UINTPTR_MAX
+# define EMACS_UINTPTR uintptr_t
+#else
+# define EMACS_UINTPTR EMACS_UINT
+#endif
+
 /* Extra internal type checking?  */
 
 #ifdef ENABLE_CHECKING
@@ -398,7 +411,7 @@
 #ifdef USE_LSB_TAG
 
 #define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1)
-#define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) (a)) & TYPEMASK))
+#define XTYPE(a) ((enum Lisp_Type) ((a) & TYPEMASK))
 #ifdef USE_2_TAGS_FOR_INTS
 # define XINT(a) (((EMACS_INT) (a)) >> (GCTYPEBITS - 1))
 # define XUINT(a) (((EMACS_UINT) (a)) >> (GCTYPEBITS - 1))
@@ -408,11 +421,11 @@
 # define XUINT(a) (((EMACS_UINT) (a)) >> GCTYPEBITS)
 # define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS)
 #endif
-#define XSET(var, type, ptr)					\
-    (eassert (XTYPE (ptr) == 0), /* Check alignment.  */	\
-     (var) = ((EMACS_INT) (type)) | ((EMACS_INT) (ptr)))
+#define XSET(var, type, ptr)						\
+    (eassert (XTYPE ((EMACS_INTPTR) (ptr)) == 0), /* Check alignment.  */ \
+     (var) = (type) | (EMACS_INTPTR) (ptr))
 
-#define XPNTR(a) ((EMACS_INT) ((a) & ~TYPEMASK))
+#define XPNTR(a) ((EMACS_INTPTR) ((a) & ~TYPEMASK))
 
 #else  /* not USE_LSB_TAG */
 
@@ -446,14 +459,14 @@
 
 #define XSET(var, type, ptr)				  \
    ((var) = ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \
-	     + ((EMACS_INT) (ptr) & VALMASK)))
+	     + ((EMACS_INTPTR) (ptr) & VALMASK)))
 
 #ifdef DATA_SEG_BITS
 /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers
    which were stored in a Lisp_Object */
-#define XPNTR(a) ((EMACS_UINT) (((a) & VALMASK) | DATA_SEG_BITS))
+#define XPNTR(a) ((EMACS_UINTPTR) (((a) & VALMASK)) | DATA_SEG_BITS))
 #else
-#define XPNTR(a) ((EMACS_UINT) ((a) & VALMASK))
+#define XPNTR(a) ((EMACS_UINTPTR) ((a) & VALMASK))
 #endif
 
 #endif /* not USE_LSB_TAG */
@@ -479,7 +492,7 @@
 /* Some versions of gcc seem to consider the bitfield width when issuing
    the "cast to pointer from integer of different size" warning, so the
    cast is here to widen the value back to its natural size.  */
-# define XPNTR(v) ((EMACS_INT)((v).s.val) << GCTYPEBITS)
+# define XPNTR(v) ((EMACS_INTPTR) (v).s.val << GCTYPEBITS)
 
 #else  /* !USE_LSB_TAG */
 
@@ -495,9 +508,9 @@
 #ifdef DATA_SEG_BITS
 /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers
    which were stored in a Lisp_Object */
-#define XPNTR(a) (XUINT (a) | DATA_SEG_BITS)
+#define XPNTR(a) ((EMACS_INTPTR) (XUINT (a) | DATA_SEG_BITS))
 #else
-#define XPNTR(a) ((EMACS_INT) XUINT (a))
+#define XPNTR(a) ((EMACS_INTPTR) XUINT (a))
 #endif
 
 #endif	/* !USE_LSB_TAG */
@@ -1814,8 +1827,8 @@
     XSETCDR ((x), tmp);			\
   } while (0)
 
-/* Cast pointers to this type to compare them.  Some machines want int.  */
-#define PNTR_COMPARISON_TYPE EMACS_UINT
+/* Cast pointers to this type to compare them.  */
+#define PNTR_COMPARISON_TYPE EMACS_UINTPTR
 \f
 /* Define a built-in function for calling from Lisp.
  `lname' should be the name to give the function in Lisp,
@@ -3353,7 +3366,7 @@
 extern void child_setup_tty (int);
 extern void setup_pty (int);
 extern int set_window_size (int, int, int);
-extern long get_random (void);
+extern EMACS_INT get_random (void);
 extern void seed_random (long);
 extern int emacs_open (const char *, int, int);
 extern int emacs_close (int);

=== modified file 'src/lread.c'
--- src/lread.c	2011-04-25 21:34:39 +0000
+++ src/lread.c	2011-04-29 07:55:25 +0000
@@ -19,7 +19,6 @@
 
 
 #include <config.h>
-#include <inttypes.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -3611,9 +3610,9 @@
 
 /* oblookup stores the bucket number here, for the sake of Funintern.  */
 
-static int oblookup_last_bucket_number;
+static size_t oblookup_last_bucket_number;
 
-static int hash_string (const char *ptr, int len);
+static size_t hash_string (const char *ptr, size_t len);
 
 /* Get an error if OBARRAY is not an obarray.
    If it is one, return it.  */
@@ -3755,7 +3754,7 @@
   (Lisp_Object name, Lisp_Object obarray)
 {
   register Lisp_Object string, tem;
-  int hash;
+  size_t hash;
 
   if (NILP (obarray)) obarray = Vobarray;
   obarray = check_obarray (obarray);
@@ -3824,8 +3823,8 @@
 Lisp_Object
 oblookup (Lisp_Object obarray, register const char *ptr, EMACS_INT size, EMACS_INT size_byte)
 {
-  int hash;
-  int obsize;
+  size_t hash;
+  size_t obsize;
   register Lisp_Object tail;
   Lisp_Object bucket, tem;
 
@@ -3858,21 +3857,21 @@
   return tem;
 }
 
-static int
-hash_string (const char *ptr, int len)
+static size_t
+hash_string (const char *ptr, size_t len)
 {
   register const char *p = ptr;
   register const char *end = p + len;
   register unsigned char c;
-  register int hash = 0;
+  register size_t hash = 0;
 
   while (p != end)
     {
       c = *p++;
       if (c >= 0140) c -= 40;
-      hash = ((hash<<3) + (hash>>28) + c);
+      hash = (hash << 3) + (hash >> (CHAR_BIT * sizeof hash - 4)) + c;
     }
-  return hash & 07777777777;
+  return hash;
 }
 \f
 void

=== modified file 'src/menu.c'
--- src/menu.c	2011-04-16 15:11:41 +0000
+++ src/menu.c	2011-04-29 07:54:43 +0000
@@ -800,9 +800,9 @@
 	  if (!NILP (descrip))
 	    wv->lkey = descrip;
 	  wv->value = 0;
-	  /* The EMACS_INT cast avoids a warning.  There's no problem
+	  /* The EMACS_INTPTR cast avoids a warning.  There's no problem
 	     as long as pointers have enough bits to hold small integers.  */
-	  wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0);
+	  wv->call_data = (!NILP (def) ? (void *) (EMACS_INTPTR) i : 0);
 	  wv->enabled = !NILP (enable);
 
 	  if (NILP (type))
@@ -911,9 +911,9 @@
       else
 	{
 	  entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE];
-	  /* The EMACS_INT cast avoids a warning.  There's no problem
+	  /* Treat the pointer as an integer.  There's no problem
 	     as long as pointers have enough bits to hold small integers.  */
-	  if ((int) (EMACS_INT) client_data == i)
+	  if ((EMACS_INTPTR) client_data == i)
 	    {
 	      int j;
 	      struct input_event buf;

=== modified file 'src/process.c'
--- src/process.c	2011-04-26 06:17:52 +0000
+++ src/process.c	2011-04-29 07:55:25 +0000
@@ -28,9 +28,6 @@
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <setjmp.h>
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -4539,7 +4536,7 @@
              some data in the TCP buffers so that select works, but
              with custom pull/push functions we need to check if some
              data is available in the buffers manually.  */
-          if (nfds == 0 && 
+          if (nfds == 0 &&
               wait_proc && wait_proc->gnutls_p /* Check for valid process.  */
               /* Do we have pending data?  */
               && gnutls_record_check_pending (wait_proc->gnutls_state) > 0)

=== modified file 'src/sysdep.c'
--- src/sysdep.c	2011-04-26 06:17:52 +0000
+++ src/sysdep.c	2011-04-28 08:18:53 +0000
@@ -1760,23 +1760,14 @@
  * Build a full Emacs-sized word out of whatever we've got.
  * This suffices even for a 64-bit architecture with a 15-bit rand.
  */
-long
+EMACS_INT
 get_random (void)
 {
-  long val = random ();
-#if VALBITS > RAND_BITS
-  val = (val << RAND_BITS) ^ random ();
-#if VALBITS > 2*RAND_BITS
-  val = (val << RAND_BITS) ^ random ();
-#if VALBITS > 3*RAND_BITS
-  val = (val << RAND_BITS) ^ random ();
-#if VALBITS > 4*RAND_BITS
-  val = (val << RAND_BITS) ^ random ();
-#endif /* need at least 5 */
-#endif /* need at least 4 */
-#endif /* need at least 3 */
-#endif /* need at least 2 */
-  return val & ((1L << VALBITS) - 1);
+  EMACS_UINT val = 0;
+  int i;
+  for (i = 0; i < (VALBITS + RAND_BITS - 1) / RAND_BITS; i++)
+    val = (val << RAND_BITS) ^ random ();
+  return val & (((EMACS_INT) 1 << VALBITS) - 1);
 }
 
 #ifndef HAVE_STRERROR

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2011-04-26 06:17:52 +0000
+++ src/xdisp.c	2011-04-29 07:54:43 +0000
@@ -8737,7 +8737,7 @@
   window_height_changed_p
     = with_echo_area_buffer (w, display_last_displayed_message_p,
 			     display_echo_area_1,
-			     (EMACS_INT) w, Qnil, 0, 0);
+			     (EMACS_INTPTR) w, Qnil, 0, 0);
 
   if (no_message_p)
     echo_area_buffer[i] = Qnil;
@@ -8756,7 +8756,8 @@
 static int
 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
 {
-  struct window *w = (struct window *) a1;
+  EMACS_INTPTR i1 = a1;
+  struct window *w = (struct window *) i1;
   Lisp_Object window;
   struct text_pos start;
   int window_height_changed_p = 0;
@@ -8798,7 +8799,8 @@
 	resize_exactly = Qnil;
 
       resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
-					 (EMACS_INT) w, resize_exactly, 0, 0);
+					 (EMACS_INTPTR) w, resize_exactly,
+					 0, 0);
       if (resized_p)
 	{
 	  ++windows_or_buffers_changed;
@@ -8818,7 +8820,8 @@
 static int
 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
 {
-  return resize_mini_window ((struct window *) a1, !NILP (exactly));
+  EMACS_INTPTR i1 = a1;
+  return resize_mini_window ((struct window *) i1, !NILP (exactly));
 }
 
 
@@ -8984,7 +8987,7 @@
   else
     {
       with_echo_area_buffer (0, 0, current_message_1,
-			     (EMACS_INT) &msg, Qnil, 0, 0);
+			     (EMACS_INTPTR) &msg, Qnil, 0, 0);
       if (NILP (msg))
 	echo_area_buffer[0] = Qnil;
     }
@@ -8996,7 +8999,8 @@
 static int
 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
 {
-  Lisp_Object *msg = (Lisp_Object *) a1;
+  EMACS_INTPTR i1 = a1;
+  Lisp_Object *msg = (Lisp_Object *) i1;
 
   if (Z > BEG)
     *msg = make_buffer_string (BEG, Z, 1);
@@ -9127,7 +9131,7 @@
        || (STRINGP (string) && STRING_MULTIBYTE (string)));
 
   with_echo_area_buffer (0, -1, set_message_1,
-			 (EMACS_INT) s, string, nbytes, multibyte_p);
+			 (EMACS_INTPTR) s, string, nbytes, multibyte_p);
   message_buf_print = 0;
   help_echo_showing_p = 0;
 }
@@ -9141,7 +9145,8 @@
 static int
 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
 {
-  const char *s = (const char *) a1;
+  EMACS_INTPTR i1 = a1;
+  const char *s = (const char *) i1;
   const unsigned char *msg = (const unsigned char *) s;
   Lisp_Object string = a2;
 

=== modified file 'src/xmenu.c'
--- src/xmenu.c	2011-04-25 21:34:39 +0000
+++ src/xmenu.c	2011-04-29 07:54:43 +0000
@@ -1139,9 +1139,9 @@
 	  wv->help = Qnil;
 	  /* This prevents lwlib from assuming this
 	     menu item is really supposed to be empty.  */
-	  /* The EMACS_INT cast avoids a warning.
+	  /* The EMACS_INTPTR cast avoids a warning.
 	     This value just has to be different from small integers.  */
-	  wv->call_data = (void *) (EMACS_INT) (-1);
+	  wv->call_data = (void *) (EMACS_INTPTR) (-1);
 
 	  if (prev_wv)
 	    prev_wv->next = wv;
@@ -1876,9 +1876,9 @@
 static void
 dialog_selection_callback (GtkWidget *widget, gpointer client_data)
 {
-  /* The EMACS_INT cast avoids a warning.  There's no problem
+  /* Treat the pointer as an integer.  There's no problem
      as long as pointers have enough bits to hold small integers.  */
-  if ((int) (EMACS_INT) client_data != -1)
+  if ((EMACS_INTPTR) client_data != -1)
     menu_item_selection = (Lisp_Object *) client_data;
 
   popup_activated_flag = 0;

# Begin bundle
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
UJCkof7e




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29  8:08 bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts Paul Eggert
@ 2011-04-29  8:49 ` Eli Zaretskii
  2011-04-29  9:06   ` Paul Eggert
  2011-04-29  8:56 ` support " Paul Eggert
  1 sibling, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2011-04-29  8:49 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

> Date: Fri, 29 Apr 2011 01:08:27 -0700
> From: Paul Eggert <eggert@cs.ucla.edu>
> 
> Currently, the Emacs C-language code assumes that EMACS_INT and
> pointers have the same width.  This is true of current ports, but I'd
> like to create a 32-bit port with 64-bit EMACS_INT, so that Emacs is
> not arbitrarily restricted by its small integer range when editing
> large files on 32-bit hosts.  I'll call this a "32+64-bit port".

Thank you for doing this.

> The main change in this patch is to introduce the types EMACS_INTPTR
> and EMACS_UINTPTR, which are like EMACS_INT and EMACS_UINT but are
> defined to be just wide enough to represent a pointer.

Maybe it's just me, but I'm slightly worried by these names: they
sound as if they represent pointers, but in fact you use them as
integer types to avoid compiler warnings and casts (even though you
used pointer types such as intptr_t to define these macros).  How
about EMACS_LONG and EMACS_ULONG instead?  Or maybe EMACS_LONGEST and
EMACS_ULONGEST, or just LONGEST and ULONGEST?  IOW, wouldn't it be
better to have names that tell explicitly they are integers, not
pointers?

Also, wrt changes such as this one:

> -  if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
> +  if (data != NULL && data == (void *) XPNTR (QCdbus_session_bus))

I wonder if we aren't obfuscating the code a bit too much, since XHASH
says something about its argument, while XPNTR is too general to
convey any such useful information.  Unless, that is, you are saying
that the use of XHASH here was bogus to begin with, and all that was
needed was a pointer.

> Step 2 will change EMACS_INT to be 64 bits on 32+64-bit ports.
> That is a bigger deal, and I'll send a later email about it.

When you do that, please don't hardwire "long long" for the 32+64-bit
builds.  That type is not standard enough in C90; in particular the
MSVC compiler we still support for Windows doesn't have it, but it
does have compatible __int64 and __uint64 types.  Using an
Emacs-specific typedef or macro will help adapting the MSVC Windows
build (and probably others that don't use GCC) to this new
configuration.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* support 64-bit EMACS_INT on 32-bit hosts
  2011-04-29  8:08 bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts Paul Eggert
  2011-04-29  8:49 ` Eli Zaretskii
@ 2011-04-29  8:56 ` Paul Eggert
  1 sibling, 0 replies; 19+ messages in thread
From: Paul Eggert @ 2011-04-29  8:56 UTC (permalink / raw)
  To: emacs-devel

On 04/29/11 01:08, Paul Eggert wrote:

> Step 2 will change EMACS_INT to be 64 bits on 32+64-bit ports.
> That is a bigger deal, and I'll send a later email about it.

Here's a simple patch to do this.  With this patch (atop the previous one),
I've successfully used Emacs to edit a 2 GB file on an x86 (32-bit)
platform.  I've only done very limited testing with this patch,
though, and I don't plan to install this patch right now; it needs
more testing.  However, I thought I'd publish it now as a heads-up.

* lisp.h: Prefer 64-bit EMACS_INT if available.
(EMACS_INT, EMACS_UINT, BITS_PER_EMACS_INT, pI): Define to 64-bit
on 32-bit hosts that have 64-bit int, so that they can access
large files.
=== modified file 'src/lisp.h'
--- src/lisp.h	2011-04-29 07:54:43 +0000
+++ src/lisp.h	2011-04-29 08:48:05 +0000
@@ -44,7 +44,16 @@
 #ifndef EMACS_UINT
 #define EMACS_UINT unsigned long
 #endif
-#else /* not _LP64 */
+#elif /* !_LP64 && */ BITS_PER_LONG < BITS_PER_LONG_LONG
+#ifndef EMACS_INT
+#define EMACS_INT long long
+#define BITS_PER_EMACS_INT BITS_PER_LONG_LONG
+#define pI "ll"
+#endif
+#ifndef EMACS_UINT
+#define EMACS_UINT unsigned long long
+#endif
+#else /* ! (_LP64 || BITS_PER_LONG < BITS_PER_LONG_LONG) */
 #ifndef EMACS_INT
 #define EMACS_INT int
 #define BITS_PER_EMACS_INT BITS_PER_INT




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29  8:49 ` Eli Zaretskii
@ 2011-04-29  9:06   ` Paul Eggert
  2011-04-29  9:17     ` Eli Zaretskii
                       ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Paul Eggert @ 2011-04-29  9:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 04/29/11 01:49, Eli Zaretskii wrote:

> Maybe it's just me, but I'm slightly worried by these names: they
> sound as if they represent pointers,

Yes, that's exactly what they're for.  EMACS_INTPTR is the Emacs
analog of the standard C type intptr_t, which is a integer type that
is wide enough to hold a pointer, i.e., one can convert from void * to
intptr_t and back again without losing information.

The name "intptr" may be a bit confusing to a reader who doesn't
know C99, but once you're used to the standard meaning, any other name
would sound weird.

> you use them as integer types to avoid compiler warnings and casts
> (even though you used pointer types such as intptr_t to define these macros).

No, intptr_t is an integer type; it's not a pointer type.

> How about EMACS_LONG and EMACS_ULONG instead?

That wouldn't be good, because in a typical 32+64-bit host, EMACS_LONG
would be narrower than EMACS_INT.

>> > -  if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
>> > +  if (data != NULL && data == (void *) XPNTR (QCdbus_session_bus))
> I wonder if we aren't obfuscating the code a bit too much, since XHASH
> says something about its argument, while XPNTR is too general to
> convey any such useful information.  Unless, that is, you are saying
> that the use of XHASH here was bogus to begin with, and all that was
> needed was a pointer.

Yes, that's what it's saying.  void * is supposed to hold only a
pointer: in general it can't hold a pointer plus a tag.  So the
old code wasn't correct.  (It was good enough for the current ports,
but not good enough for a 32+64-bit port.)

>> > Step 2 will change EMACS_INT to be 64 bits on 32+64-bit ports.
>> > That is a bigger deal, and I'll send a later email about it.
> When you do that, please don't hardwire "long long" for the 32+64-bit
> builds.  That type is not standard enough in C90; in particular the
> MSVC compiler we still support for Windows doesn't have it, but it
> does have compatible __int64 and __uint64 types.

Thanks, I hadn't thought of that.  Before I got your email I already
sent out a simple patch
<http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00908.html>
that did not use __int64 (so it continued to use 32-bit int on
Windows).  I will look into extending that patch, so that it also works with
__int64.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29  9:06   ` Paul Eggert
@ 2011-04-29  9:17     ` Eli Zaretskii
  2011-04-29 16:04     ` Stefan Monnier
  2011-04-30  6:54     ` Paul Eggert
  2 siblings, 0 replies; 19+ messages in thread
From: Eli Zaretskii @ 2011-04-29  9:17 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

> Date: Fri, 29 Apr 2011 02:06:15 -0700
> From: Paul Eggert <eggert@cs.ucla.edu>
> Cc: emacs-devel@gnu.org
> 
> The name "intptr" may be a bit confusing to a reader who doesn't
> know C99, but once you're used to the standard meaning, any other name
> would sound weird.

I'll let others chime in if they want.  If it's just me that is
confused, I guess I'll survive this culture shock.

> > When you do that, please don't hardwire "long long" for the 32+64-bit
> > builds.  That type is not standard enough in C90; in particular the
> > MSVC compiler we still support for Windows doesn't have it, but it
> > does have compatible __int64 and __uint64 types.
> 
> Thanks, I hadn't thought of that.  Before I got your email I already
> sent out a simple patch
> <http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00908.html>
> that did not use __int64 (so it continued to use 32-bit int on
> Windows).  I will look into extending that patch, so that it also works with
> __int64.

Thanks.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29  9:06   ` Paul Eggert
  2011-04-29  9:17     ` Eli Zaretskii
@ 2011-04-29 16:04     ` Stefan Monnier
  2011-04-29 17:10       ` Eli Zaretskii
  2011-04-30  1:37       ` Paul Eggert
  2011-04-30  6:54     ` Paul Eggert
  2 siblings, 2 replies; 19+ messages in thread
From: Stefan Monnier @ 2011-04-29 16:04 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Eli Zaretskii, emacs-devel

Let me first say that I'm not terribly excited by this idea of
a 32+64bit compilation option: ignoring the fact that many 32bit OSes do
not provide a full 4GB virtual address space to the Emacs process, such
a change can only bump the limit from 512MB to less than 4GB.
Of course, it will satisfy some particular uses, but it won't remove the
fundamental problem.

> The name "intptr" may be a bit confusing to a reader who doesn't
> know C99, but once you're used to the standard meaning, any other name
> would sound weird.

Makes me wonder: why use EMACS_INTPTR rather than intptr_t?

>>> > -  if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
>>> > +  if (data != NULL && data == (void *) XPNTR (QCdbus_session_bus))
>> I wonder if we aren't obfuscating the code a bit too much, since XHASH
>> says something about its argument, while XPNTR is too general to
>> convey any such useful information.  Unless, that is, you are saying
>> that the use of XHASH here was bogus to begin with, and all that was
>> needed was a pointer.
> Yes, that's what it's saying.  void * is supposed to hold only a
> pointer: in general it can't hold a pointer plus a tag.  So the
> old code wasn't correct.  (It was good enough for the current ports,
> but not good enough for a 32+64-bit port.)

The old code is correct all right: void* can hold a 32bit value, and
XHASH takes a 32bit value and returns a 32bit value (it's a perfect hash
function, in a sense).  OTOH XPNTR takes a 32bit value and returns
a 29bit value, so there's loss of information, whereas XHASH was
specially designed to return an integer value without any loss of
information.  And indeed, if the user passes the right Lisp integer at
the right place, the above new test may return true even though an
integer should clearly not be treated as equal to a symbol.

I.e. XPNTR should never be used on an INTEGERP value.  For other values
it's OK since they're all boxed as pointers, and the 29bit returned by
XPNTR has only thrown away redundant info (tho this redundancy may be
difficult to recover).

So it might be OK to replace XHASH with XPNTR, but only if you catch the
INTEGERP case beforehand.

> @@ -2144,7 +2144,7 @@
>         We used to use 0 here, but that leads to accidental sharing in
>         purecopy's hash-consing, so we use a (hopefully) unique integer
>         instead.  */
> -    docstring = make_number (XHASH (function));
> +    docstring = make_number (XPNTR (function));
>    return Ffset (function,
>  		Fpurecopy (list5 (Qautoload, file, docstring,
>  				  interactive, type)));

You lost me here.  make_number doesn't take a pointer as argument.
Even tho it's called "hash" it should not lose any information, so XHASH
is the right thing to use here, AFAICT.

>    if (wimage)
>      {
> -      /* The EMACS_INT cast avoids a warning. */
> +      EMACS_INTPTR ii = i;
> +      gpointer gi = (gpointer) ii;
> +

I saw various places where you do something similar.  Is there
a particular reason why you use an intermediate var rather than use the
more concise "(gpointer) (EMACS_INTPTR) i"?


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29 16:04     ` Stefan Monnier
@ 2011-04-29 17:10       ` Eli Zaretskii
  2011-04-29 17:32         ` Lars Magne Ingebrigtsen
  2011-04-29 18:50         ` David De La Harpe Golden
  2011-04-30  1:37       ` Paul Eggert
  1 sibling, 2 replies; 19+ messages in thread
From: Eli Zaretskii @ 2011-04-29 17:10 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: eggert, emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: Eli Zaretskii <eliz@gnu.org>,  emacs-devel@gnu.org
> Date: Fri, 29 Apr 2011 13:04:07 -0300
> 
> Let me first say that I'm not terribly excited by this idea of
> a 32+64bit compilation option: ignoring the fact that many 32bit OSes do
> not provide a full 4GB virtual address space to the Emacs process, such
> a change can only bump the limit from 512MB to less than 4GB.
> Of course, it will satisfy some particular uses, but it won't remove the
> fundamental problem.

Well, I beg to differ: I think an eight-fold increase in the size of
files we can visit on a 32-bit system _is_ a big deal.  At least in
the year 2011, files larger than 4GB are extremely rare, while files
larger than 512MB are quite common (I bump into them every day on my
daytime job).



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29 17:10       ` Eli Zaretskii
@ 2011-04-29 17:32         ` Lars Magne Ingebrigtsen
  2011-04-29 17:45           ` Paul Eggert
  2011-04-29 18:50         ` David De La Harpe Golden
  1 sibling, 1 reply; 19+ messages in thread
From: Lars Magne Ingebrigtsen @ 2011-04-29 17:32 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

> Well, I beg to differ: I think an eight-fold increase in the size of
> files we can visit on a 32-bit system _is_ a big deal.  At least in
> the year 2011, files larger than 4GB are extremely rare, while files
> larger than 512MB are quite common (I bump into them every day on my
> daytime job).

Will this extension allow us to have (almost) 64-bit Emacs Lisp integers
on 32-bit system?  In that case, I think it's a rather momentous
extension -- there's a lot of numerical data that Gnus has to deal with
(for instance, IMAP sequence numbers) that will overflow, er, 28 bit
data (or whatever the limit is on 32-bit hosts these days), and requires
somewhat awkward work-arounds.

So if I understand this correctly (and I might not do -- it's Friday),
it seems like a really great development.

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29 17:32         ` Lars Magne Ingebrigtsen
@ 2011-04-29 17:45           ` Paul Eggert
  0 siblings, 0 replies; 19+ messages in thread
From: Paul Eggert @ 2011-04-29 17:45 UTC (permalink / raw)
  To: emacs-devel

On 04/29/11 10:32, Lars Magne Ingebrigtsen wrote:
> Will this extension allow us to have (almost) 64-bit Emacs Lisp integers
> on 32-bit system?

Yes, they work too.  I've tested this a bit, but need to test it some more.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29 17:10       ` Eli Zaretskii
  2011-04-29 17:32         ` Lars Magne Ingebrigtsen
@ 2011-04-29 18:50         ` David De La Harpe Golden
  2011-04-30  5:00           ` Stephen J. Turnbull
  1 sibling, 1 reply; 19+ messages in thread
From: David De La Harpe Golden @ 2011-04-29 18:50 UTC (permalink / raw)
  To: emacs-devel

On 29/04/11 18:10, Eli Zaretskii wrote:
>> From: Stefan Monnier<monnier@iro.umontreal.ca>
>> Cc: Eli Zaretskii<eliz@gnu.org>,  emacs-devel@gnu.org
>> Date: Fri, 29 Apr 2011 13:04:07 -0300
>>
>> Let me first say that I'm not terribly excited by this idea of
>> a 32+64bit compilation option: ignoring the fact that many 32bit OSes do
>> not provide a full 4GB virtual address space to the Emacs process, such
>> a change can only bump the limit from 512MB to less than 4GB.
>> Of course, it will satisfy some particular uses, but it won't remove the
>> fundamental problem.
>
> Well, I beg to differ: I think an eight-fold increase in the size of
> files we can visit on a 32-bit system _is_ a big deal.


Meh. IMO the aim should be proper lispy bignums. GNU does already have a 
C bignum (and other stuff) library (GMP) [1] that emacs could link 
against, after all!  I think Paul's changes may help somewhat with that 
goal anyway (emacs integers would be further divorced from C ints), just 
saying.


[1] http://gmplib.org/



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29 16:04     ` Stefan Monnier
  2011-04-29 17:10       ` Eli Zaretskii
@ 2011-04-30  1:37       ` Paul Eggert
  2011-05-02 14:46         ` Stefan Monnier
  1 sibling, 1 reply; 19+ messages in thread
From: Paul Eggert @ 2011-04-30  1:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel

On 04/29/11 09:04, Stefan Monnier wrote:

> why use EMACS_INTPTR rather than intptr_t?

An excess of caution. :-)  I'll change it to intptr_t.

>>>>> >>> > -  if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
>>>>> >>> > +  if (data != NULL && data == (void *) XPNTR (QCdbus_session_bus))
> ...
> I.e. XPNTR should never be used on an INTEGERP value.

OK, thanks.  Since busses are always symbols, I'll change that to:

  if (SYMBOLP (QCdbus_session_bus) && XSYMBOL (QCdbus_session_bus) == data)

and similarly change the other two XPNTRs to SYMBOLP-guarded XSYMBOLs.

With this change, there shouldn't be a need to cast to void *, right?
(A cast would be needed if Emacs were intended to be compilable by
a C++ compiler, but I assume that's not a goal.)

>> > -    docstring = make_number (XHASH (function));
>> > +    docstring = make_number (XPNTR (function));
> You lost me here.  make_number doesn't take a pointer as argument.
> Even tho it's called "hash" it should not lose any information, so XHASH
> is the right thing to use here, AFAICT.

But 'function' is a Lisp_Object, so it's already a tagged pointer
that's possibly shifted.  make_number will tag it and possibly shift
it again, which can lose info about the pointer; and this means
purecopy's hash-consing could mess up.

In other words, the XHASH can cause a bug even on an ordinary 32-bit host.

XPNTR can't lose any information about the actual pointer, since
'function' is guaranteed to be a symbol here.  That's why this code is
different from the dbus code mentioned above.

>> > -      /* The EMACS_INT cast avoids a warning. */
>> > +      EMACS_INTPTR ii = i;
>> > +      gpointer gi = (gpointer) ii;
> Is there a particular reason why you use an intermediate var rather than use the
> more concise "(gpointer) (EMACS_INTPTR) i"?

To avoid a cast.  If you prefer conciseness to avoiding these casts, I
can easily change these to the more-concise form.

Thanks for the careful review.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29 18:50         ` David De La Harpe Golden
@ 2011-04-30  5:00           ` Stephen J. Turnbull
  0 siblings, 0 replies; 19+ messages in thread
From: Stephen J. Turnbull @ 2011-04-30  5:00 UTC (permalink / raw)
  To: David De La Harpe Golden; +Cc: emacs-devel

David De La Harpe Golden writes:

 > Meh. IMO the aim should be proper lispy bignums.

XEmacs and SXEmacs, of course, already have bignums (and I think
SXEmacs has quaternions and maybe octonions, and I think somebody is
planning to implement Robinsonian infinitesimals and transfinite
ordinals, just in case your buffers get that big or small ;-).

The problem is that they are far too slow for use in redisplay and
Mule.  So you need an intermediate, fast (enough) integer form for
those cases anyway.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-29  9:06   ` Paul Eggert
  2011-04-29  9:17     ` Eli Zaretskii
  2011-04-29 16:04     ` Stefan Monnier
@ 2011-04-30  6:54     ` Paul Eggert
  2011-04-30  7:30       ` Eli Zaretskii
  2 siblings, 1 reply; 19+ messages in thread
From: Paul Eggert @ 2011-04-30  6:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 04/29/11 02:06, Paul Eggert wrote:
> I will look into extending that patch, so that it also works with
> __int64.

Here's one way to do that.  Add this to nt/config.nt,
after the BITS_PER_LONG definition:

#if (defined __MINGW32__ \
     || 1400 <= _MSC_VER || (1310 <= _MSC_VER && defined _MSC_EXTENSIONS))
/* C99-style long long and "%lld" both work, so use them.  */
# define BITS_PER_LONG_LONG 64
#elif 1200 <= _MSC_VER
/* Use pre-C99-style 64-bit integers.  */
# define EMACS_INT __int64
# define BITS_PER_EMACS_INT 64
# define pI "I64"
#endif

I inferred the above by looking at random stuff
off the net, and haven't actually tested it; quite possibly
it's not exactly right for Emacs but something like this should work.

Also, I plan to simplify the rats-nest of EMACS_INT ifdefs in lisp.h
to the following.  This should make this stuff easier to follow.

#ifndef EMACS_INT
# if BITS_PER_LONG < BITS_PER_LONG_LONG
#  define EMACS_INT long long
#  define BITS_PER_EMACS_INT BITS_PER_LONG_LONG
#  define pI "ll"
# elif BITS_PER_INT < BITS_PER_LONG
#  define EMACS_INT long
#  define BITS_PER_EMACS_INT BITS_PER_LONG
#  define pI "l"
# else
#  define EMACS_INT int
#  define BITS_PER_EMACS_INT BITS_PER_INT
#  define pI ""
# endif
#endif
#ifndef EMACS_UINT
# define EMACS_UINT unsigned EMACS_INT
#endif



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-30  6:54     ` Paul Eggert
@ 2011-04-30  7:30       ` Eli Zaretskii
  0 siblings, 0 replies; 19+ messages in thread
From: Eli Zaretskii @ 2011-04-30  7:30 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

> Date: Fri, 29 Apr 2011 23:54:50 -0700
> From: Paul Eggert <eggert@cs.ucla.edu>
> CC: emacs-devel@gnu.org
> 
> On 04/29/11 02:06, Paul Eggert wrote:
> > I will look into extending that patch, so that it also works with
> > __int64.
> 
> Here's one way to do that.  Add this to nt/config.nt,
> after the BITS_PER_LONG definition:
> 
> #if (defined __MINGW32__ \
>      || 1400 <= _MSC_VER || (1310 <= _MSC_VER && defined _MSC_EXTENSIONS))
> /* C99-style long long and "%lld" both work, so use them.  */
> # define BITS_PER_LONG_LONG 64
> #elif 1200 <= _MSC_VER
> /* Use pre-C99-style 64-bit integers.  */
> # define EMACS_INT __int64
> # define BITS_PER_EMACS_INT 64
> # define pI "I64"
> #endif

Thanks!

> I inferred the above by looking at random stuff
> off the net, and haven't actually tested it; quite possibly
> it's not exactly right for Emacs but something like this should work.

I think it is correct, except for one minor gotcha: _MSC_EXTENSIONS do
NOT enable a `long long' data type in versions of MSVC before 1400.
_MSC_EXTENSIONS enable the use of __int64 in all versions of the MS
compiler.  Also, _MSC_EXTENSIONS is on by default, so there's no need
to test for it explicitly.  According to my reading of the MS
documentation, the `long long' data type is supported by MSVC only
starting from version 1400; before that, we should use __int64.

So I would change the above to say

#if (defined __MINGW32__ || 1400 <= _MSC_VER)
/* C99-style long long and "%lld" both work, so use them.  */
# define BITS_PER_LONG_LONG 64
#elif 1200 <= _MSC_VER
/* Use pre-C99-style 64-bit integers.  */
# define EMACS_INT __int64
# define BITS_PER_EMACS_INT 64
# define pI "I64"
#endif

> Also, I plan to simplify the rats-nest of EMACS_INT ifdefs in lisp.h
> to the following.  This should make this stuff easier to follow.

That'd be fine, thanks.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-04-30  1:37       ` Paul Eggert
@ 2011-05-02 14:46         ` Stefan Monnier
  2011-05-02 16:09           ` Paul Eggert
  0 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2011-05-02 14:46 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Eli Zaretskii, emacs-devel

>> why use EMACS_INTPTR rather than intptr_t?
> An excess of caution. :-)  I'll change it to intptr_t.

Thanks; having to use EMACS_INT rather than `int' is painful enough
already.

> OK, thanks.  Since busses are always symbols, I'll change that to:
>   if (SYMBOLP (QCdbus_session_bus) && XSYMBOL (QCdbus_session_bus) == data)

Sounds good.

> With this change, there shouldn't be a need to cast to void *, right?

Possibly.  I'd ask Paul for these kinds of details ;-)

> (A cast would be needed if Emacs were intended to be compilable by
> a C++ compiler, but I assume that's not a goal.)

It's not a goal, indeed, tho IIRC someone recently installed changes to
make it possible to compile with a C++ compiler (or was it for ObjC?
can't remember).

>>> > -    docstring = make_number (XHASH (function));
>>> > +    docstring = make_number (XPNTR (function));
>> You lost me here.  make_number doesn't take a pointer as argument.
>> Even tho it's called "hash" it should not lose any information, so XHASH
>> is the right thing to use here, AFAICT.

> But 'function' is a Lisp_Object, so it's already a tagged pointer
> that's possibly shifted.  make_number will tag it and possibly shift
> it again, which can lose info about the pointer; and this means
> purecopy's hash-consing could mess up.

> In other words, the XHASH can cause a bug even on an ordinary 32-bit host.

> XPNTR can't lose any information about the actual pointer, since
> 'function' is guaranteed to be a symbol here.  That's why this code is
> different from the dbus code mentioned above.

Yes and no: that's true for some platforms, but in most platforms
(including Windows, Mac OS X, and GNU/Linux), the 3bit tag is in the
LSB, so the difference between XHASH and XPNTR is not the shifting
(neither does shifting in this case) but in that XPNTR masks the 3 LSB.

Now, in practice, the difference is negligible since as you point out
(and I had forgotten), those 3bits are constant since `function' is
always a symbol.  So the data "thrown away" by XPNTR doesn't contain any
significant information for hashing purposes.
E.g. sxhash uses "XPNTR (obj) >> 3" where the >>3 is there to compensate
for make_number's dropping the 3 MSB.

So I guess it's OK to drop XHASH, but please use XSYMBOL rather
than XPNTR.

>>> > -      /* The EMACS_INT cast avoids a warning. */
>>> > +      EMACS_INTPTR ii = i;
>>> > +      gpointer gi = (gpointer) ii;
>> Is there a particular reason why you use an intermediate var rather
>> than use the more concise "(gpointer) (EMACS_INTPTR) i"?
> To avoid a cast.

I'm not sure what is the formal definition of "cast" in C, but at least
from my point of view, your code performs just the same kind of coercion
as a cast.

> If you prefer conciseness to avoiding these casts, I can easily change
> these to the more-concise form.

I do prefer the more concise form, and paradoxically part of the reason
is because it is uses a explicit coercion rather than an implicit one.


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-05-02 14:46         ` Stefan Monnier
@ 2011-05-02 16:09           ` Paul Eggert
  2011-05-02 18:12             ` Stefan Monnier
  0 siblings, 1 reply; 19+ messages in thread
From: Paul Eggert @ 2011-05-02 16:09 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel

On 05/02/11 07:46, Stefan Monnier wrote:
>>>>> >>> > -      /* The EMACS_INT cast avoids a warning. */
>>>>> >>> > +      EMACS_INTPTR ii = i;
>>>>> >>> > +      gpointer gi = (gpointer) ii;
>>> >> Is there a particular reason why you use an intermediate var rather
>>> >> than use the more concise "(gpointer) (EMACS_INTPTR) i"?
>> > To avoid a cast.
> I'm not sure what is the formal definition of "cast" in C, but at least
> from my point of view, your code performs just the same kind of coercion
> as a cast.

The runtime behavior is the same, but avoiding the cast can catch more errors.
Suppose "i" is of type "struct tm *", say, and the programmer made a mistake.
Then GCC will issue a helpful diagnostic for the form with just one cast,
but it won't diagnose the more-concise form with two casts.

>> > If you prefer conciseness to avoiding these casts, I can easily change
>> > these to the more-concise form.
> I do prefer the more concise form, and paradoxically part of the reason
> is because it is uses a explicit coercion rather than an implicit one.

OK, will do (unless the above argument convinced you :-).



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-05-02 16:09           ` Paul Eggert
@ 2011-05-02 18:12             ` Stefan Monnier
  2011-05-02 19:23               ` Paul Eggert
  0 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2011-05-02 18:12 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Eli Zaretskii, emacs-devel

>>>>> >>> > -      /* The EMACS_INT cast avoids a warning. */
>>>>> >>> > +      EMACS_INTPTR ii = i;
>>>>> >>> > +      gpointer gi = (gpointer) ii;
>>>> >> Is there a particular reason why you use an intermediate var rather
>>>> >> than use the more concise "(gpointer) (EMACS_INTPTR) i"?
>>> > To avoid a cast.
>> I'm not sure what is the formal definition of "cast" in C, but at least
>> from my point of view, your code performs just the same kind of coercion
>> as a cast.

> The runtime behavior is the same, but avoiding the cast can catch more
> errors.  Suppose "i" is of type "struct tm *", say, and the programmer
> made a mistake.  Then GCC will issue a helpful diagnostic for the form
> with just one cast, but it won't diagnose the more-concise form with
> two casts.

Right, implicit coercions are indeed checked more thoroughly since the
programmer doesn't say explicitly to shut up.

My favorite choice would be to force all casts to have a more easily to
find shape (e.g. so `grep' can find them) and to split them into various
categories, so the above EMACS_INTPTR cast would be labeled as
"checked" or "safe", so the compiler can output warnings.

>>> > If you prefer conciseness to avoiding these casts, I can easily change
>>> > these to the more-concise form.
>> I do prefer the more concise form, and paradoxically part of the reason
>> is because it is uses a explicit coercion rather than an implicit one.
> OK, will do (unless the above argument convinced you :-).

Given that

  #define checked_cast(t,x) ({ t v = (x); v})

can't be written in ISO C (AFAIK), I either form will be suboptimal,
so there's no need to change the code.


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-05-02 18:12             ` Stefan Monnier
@ 2011-05-02 19:23               ` Paul Eggert
  2011-05-02 19:49                 ` Stefan Monnier
  0 siblings, 1 reply; 19+ messages in thread
From: Paul Eggert @ 2011-05-02 19:23 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel

On 05/02/11 11:12, Stefan Monnier wrote:
> Given that
> 
>   #define checked_cast(t,x) ({ t v = (x); v})
> 
> can't be written in ISO C (AFAIK), I either form will be suboptimal,
> so there's no need to change the code.

How about the following idea instead?  Put this into lisp.h:

  static inline EMACS_INTPTR to_EMACS_INTPTR (EMACS_INTPTR a) { return a; }

Then, instead of this:

  EMACS_INTPTR ii = i;
  gpointer gi = (gpointer) ii;

(which is verbose) or this:

  gpointer gi = (gpointer) (EMACS_INTPTR) i;

(which misses some silly mistakes) we can write this:

  gpointer gi = (gpointer) to_EMACS_INTPTR (i);

(which has neither problem).



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts
  2011-05-02 19:23               ` Paul Eggert
@ 2011-05-02 19:49                 ` Stefan Monnier
  0 siblings, 0 replies; 19+ messages in thread
From: Stefan Monnier @ 2011-05-02 19:49 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Eli Zaretskii, emacs-devel

>   static inline EMACS_INTPTR to_EMACS_INTPTR (EMACS_INTPTR a) { return a; }
[...]
> (which misses some silly mistakes) we can write this:
>   gpointer gi = (gpointer) to_EMACS_INTPTR (i);

While it solves this particular problem, you'd have to write one for
each and every type you may want to use, which is hideous.
So no, I'd rather not go there.


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-05-02 19:49 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-29  8:08 bookkeeping to prepare for a 64-bit EMACS_INT on 32-bit hosts Paul Eggert
2011-04-29  8:49 ` Eli Zaretskii
2011-04-29  9:06   ` Paul Eggert
2011-04-29  9:17     ` Eli Zaretskii
2011-04-29 16:04     ` Stefan Monnier
2011-04-29 17:10       ` Eli Zaretskii
2011-04-29 17:32         ` Lars Magne Ingebrigtsen
2011-04-29 17:45           ` Paul Eggert
2011-04-29 18:50         ` David De La Harpe Golden
2011-04-30  5:00           ` Stephen J. Turnbull
2011-04-30  1:37       ` Paul Eggert
2011-05-02 14:46         ` Stefan Monnier
2011-05-02 16:09           ` Paul Eggert
2011-05-02 18:12             ` Stefan Monnier
2011-05-02 19:23               ` Paul Eggert
2011-05-02 19:49                 ` Stefan Monnier
2011-04-30  6:54     ` Paul Eggert
2011-04-30  7:30       ` Eli Zaretskii
2011-04-29  8:56 ` support " Paul Eggert

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).