diff options
author | H. Peter Anvin (Intel) <hpa@zytor.com> | 2020-07-06 17:13:02 -0700 |
---|---|---|
committer | H. Peter Anvin (Intel) <hpa@zytor.com> | 2020-07-06 17:13:02 -0700 |
commit | 178148c876bd49a77e5e39aea028497c3e20acf6 (patch) | |
tree | 5b4ef94f87f52c5501220a620634278267426fd2 | |
parent | c0ab5a8be9f91e7485e64673b498e724b03c73df (diff) | |
download | nasm-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.h | 16 |
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 |