From a7f20d4328092b382c26c6d738e575c1ead9dc91 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 3 Jun 2019 15:41:05 +0200 Subject: lib: const-unaware container_of for C++ This version of container_of() should work on C++, by ditching the unavailable builtins (at the cost of no longer checking for "const" violations.) Signed-off-by: David Lamparter --- lib/compiler.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'lib/compiler.h') 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) \ ({ \ -- cgit v1.2.3