]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add macro that performs explicit static casts when using a C++ compiler
authorRenato Westphal <renato@opensourcerouting.org>
Mon, 11 Feb 2019 18:04:26 +0000 (16:04 -0200)
committerRenato Westphal <renato@opensourcerouting.org>
Tue, 12 Feb 2019 00:34:12 +0000 (22:34 -0200)
C++ doesn't support implicit casts from void pointers like C
does. And the libfrr headers have some bits of code that rely on
implicit casts in order to work. To solve this problem, add a new
"static_cast" macro that performs explicit static casts when a C++
compiler is being used, or do nothing otherwise.

NOTE: since macros are only evaluated when they are used, there
might be other macros from libfrr that will need to use "static_cast"
as well. If a header is successfully compiled using a C++ compiler,
there's no guarantee that its macros are compatible with C++. We'll
only know about such macros when they are used by C++ code, then
we'll need to adapt them one by one in the future.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
lib/linklist.h
lib/zebra.h

index 5908e97a1401be898a95da2b4f1a5a58cd98bb10..76fad45d0861c36ac99657ea660c5b2c16fd61cf 100644 (file)
@@ -295,7 +295,8 @@ extern void list_add_list(struct list *list, struct list *add);
 #define ALL_LIST_ELEMENTS(list, node, nextnode, data)                          \
        (node) = listhead(list), ((data) = NULL);                              \
        (node) != NULL                                                         \
-               && ((data) = listgetdata(node), (nextnode) = node->next, 1);   \
+               && ((data) = static_cast(data, listgetdata(node)),             \
+                   (nextnode) = node->next, 1);                               \
        (node) = (nextnode), ((data) = NULL)
 
 /* read-only list iteration macro.
@@ -306,7 +307,7 @@ extern void list_add_list(struct list *list, struct list *add);
  */
 #define ALL_LIST_ELEMENTS_RO(list, node, data)                                 \
        (node) = listhead(list), ((data) = NULL);                              \
-       (node) != NULL && ((data) = listgetdata(node), 1);                     \
+       (node) != NULL && ((data) = static_cast(data, listgetdata(node)), 1);  \
        (node) = listnextnode(node), ((data) = NULL)
 
 /* these *do not* cleanup list nodes and referenced data, as the functions
index 43ab4309c21f367522ccbd4297fc637ee80ae192..b96fb5a206834dbf414ec309dd76fe3a38f88387 100644 (file)
@@ -232,6 +232,15 @@ typedef unsigned char uint8_t;
 
 #include "zassert.h"
 
+/*
+ * Add explicit static cast only when using a C++ compiler.
+ */
+#ifdef __cplusplus
+#define static_cast(l, r) static_cast<decltype(l)>((r))
+#else
+#define static_cast(l, r) (r)
+#endif
+
 #ifndef HAVE_STRLCAT
 size_t strlcat(char *__restrict dest,
               const char *__restrict src, size_t destsize);