0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-09-22 10:43:39 -04:00

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>
This commit is contained in:
H. Peter Anvin (Intel)
2020-07-06 17:13:02 -07:00
parent c0ab5a8be9
commit 178148c876

View File

@@ -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