summaryrefslogtreecommitdiff
path: root/lib/compiler.h
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2019-06-13 08:38:05 -0400
committerGitHub <noreply@github.com>2019-06-13 08:38:05 -0400
commita8baba69aef8bdcb1e3f3eaea468e392ba6a0116 (patch)
treef2ba3a9f27d123ddbcd192f8a8095db18109cb93 /lib/compiler.h
parent230113cf7123d2d1b9c686368e44a5b320fd8fc9 (diff)
parenta7f20d4328092b382c26c6d738e575c1ead9dc91 (diff)
Merge pull request #4448 from opensourcerouting/cxx-container-of
lib: const-unaware container_of for C++
Diffstat (limited to 'lib/compiler.h')
-rw-r--r--lib/compiler.h17
1 files changed, 14 insertions, 3 deletions
diff --git a/lib/compiler.h b/lib/compiler.h
index 9ce91e3361..696fb0d040 100644
--- a/lib/compiler.h
+++ b/lib/compiler.h
@@ -173,6 +173,11 @@ extern "C" {
#endif
#endif
+#ifdef container_of
+#undef container_of
+#endif
+
+#if !(defined(__cplusplus) || defined(test__cplusplus))
/* this variant of container_of() retains 'const' on pointers without needing
* to be told to do so. The following will all work without warning:
*
@@ -191,9 +196,6 @@ extern "C" {
* struct cont *x = container_of(cp, const struct cont, member);
* struct cont *x = container_of(p, const struct cont, member);
*/
-#ifdef container_of
-#undef container_of
-#endif
#define container_of(ptr, type, member) \
(__builtin_choose_expr( \
__builtin_types_compatible_p(typeof(&((type *)0)->member), \
@@ -209,6 +211,15 @@ extern "C" {
offsetof(type, member)); \
}) \
))
+#else
+/* current C++ compilers don't have the builtins used above; so this version
+ * of the macro doesn't do the const check. */
+#define container_of(ptr, type, member) \
+ ({ \
+ const typeof(((type *)0)->member) *__mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); \
+ })
+#endif
#define container_of_null(ptr, type, member) \
({ \