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:
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user