summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2020-07-06 17:13:02 -0700
committerH. Peter Anvin (Intel) <hpa@zytor.com>2020-07-06 17:13:02 -0700
commit178148c876bd49a77e5e39aea028497c3e20acf6 (patch)
tree5b4ef94f87f52c5501220a620634278267426fd2
parentc0ab5a8be9f91e7485e64673b498e724b03c73df (diff)
downloadnasm-178148c876bd49a77e5e39aea028497c3e20acf6.tar.gz
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@zytor.com>
-rw-r--r--include/compiler.h16
1 files 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