[nasm:nasm-2.15.xx] compiler.h: safer/more portable version of offsetin()

nasm-bot for H. Peter Anvin (Intel) hpa at zytor.com
Mon Jul 6 17:15:03 PDT 2020


Commit-ID:  178148c876bd49a77e5e39aea028497c3e20acf6
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=178148c876bd49a77e5e39aea028497c3e20acf6
Author:     H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Mon, 6 Jul 2020 17:13:02 -0700
Committer:  H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Mon, 6 Jul 2020 17:13:02 -0700

compiler.h: safer/more portable version of offsetin()

Still technically not defined behavior, but this *should* work on all
reasonable or semi-reasonable systems.

Signed-off-by: H. Peter Anvin (Intel) <hpa at zytor.com>


---
 include/compiler.h | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/include/compiler.h b/include/compiler.h
index 30b8e509..b4fd3a89 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2007-2018 The NASM Authors - All Rights Reserved
+ *   Copyright 2007-2020 The NASM Authors - All Rights Reserved
  *   See the file AUTHORS included with the NASM distribution for
  *   the specific copyright holders.
  *
@@ -183,10 +183,19 @@ typedef enum bool { false, true } bool;
 # endif
 #endif
 
+/* Create a NULL pointer of the same type as the address of
+   the argument, without actually evaluating said argument. */
+#define nullas(p) (0 ? &(p) : NULL)
+
+/* Convert an offsetted NULL pointer dereference to a size_t offset.
+   Technically non-portable as taking the offset from a NULL pointer
+   is undefined behavior, but... */
+#define null_offset(p) ((size_t)((const char *)&(p) - (const char *)NULL))
+
 /* Provide a substitute for offsetof() if we don't have one.  This
    variant works on most (but not *all*) systems... */
 #ifndef offsetof
-# define offsetof(t,m) ((size_t)&(((t *)0)->m))
+# define offsetof(t,m) null_offset(((t *)NULL)->m)
 #endif
 
 /* If typeof is defined as a macro, assume we have typeof even if
@@ -200,8 +209,7 @@ typedef enum bool { false, true } bool;
 # ifdef HAVE_TYPEOF
 #  define offsetin(p,m) offsetof(typeof(p),m)
 # else
-/* Fallback, technically non-portable if p is uninitialized. */
-#  define offsetin(p,m)	((const char *)&((p).m) - (const char *)&(p))
+#  define offsetin(p,m)	null_offset(nullas(p)->m)
 # endif
 #endif
 


More information about the Nasm-commits mailing list