]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: const-unaware container_of for C++
authorDavid Lamparter <equinox@diac24.net>
Mon, 3 Jun 2019 13:41:05 +0000 (15:41 +0200)
committerDavid Lamparter <equinox@diac24.net>
Tue, 11 Jun 2019 16:45:38 +0000 (18:45 +0200)
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 <equinox@diac24.net>
lib/compiler.h
tests/lib/cxxcompat.c

index 9ce91e3361aac6fe00e865bd09779ab9c1149683..696fb0d0406fd20c56f1cec4373ad2718a412cf5 100644 (file)
@@ -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)                                   \
        ({                                                                     \
index 48fa0ec8a9f81b6452c148233191c738cc7e84cd..6624de7386f6dca16ef04aae0bf8eee86ec9e557 100644 (file)
@@ -17,6 +17,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#define test__cplusplus
+
 #include "lib/zebra.h"
 
 #include "lib/agg_table.h"
 #include "lib/zassert.h"
 #include "lib/zclient.h"
 
+PREDECL_RBTREE_UNIQ(footree)
+struct foo {
+       int dummy;
+       struct footree_item item;
+};
+static int foocmp(const struct foo *a, const struct foo *b)
+{
+       return memcmp(&a->dummy, &b->dummy, sizeof(a->dummy));
+}
+DECLARE_RBTREE_UNIQ(footree, struct foo, item, foocmp)
+
 int main(int argc, char **argv)
 {
        return 0;