[PATCH 4/4] Explicitly type void* pointers

Jani Nikula jani at nikula.org
Mon Apr 9 14:31:34 PDT 2012


Vladimir Marek <Vladimir.Marek at Oracle.COM> writes:

> Hi,
>
>> Hi, does notmuch not compile without this? IIRC talloc_steal is a macro
>> that's supposed to provide type safety (at least with GCC), and I'd be
>> hesitant about adding the casts. Please look in your talloc.h.
>
> It does not compile. It might be that I'm using Sun/Oracle CC instead of
> gcc. The error looks like this:
>
> "lib/database.cc", line 1368: Error: Cannot assign void* to const char*.

In general, that's not a difference in the C++ compilers. You can't
assign 'void *' to 'T *' in C++.

> When looking into talloc documentation, the definition seems to be:
>
> void* talloc_steal ( const void * new_ctx, const void * ptr )
>
> http://talloc.samba.org/talloc/doc/html/group__talloc.html#gaccc66139273e727183fb5bdda11ef82c
>
>
> When looking into talloc.h, it says:
>
> /* try to make talloc_set_destructor() and talloc_steal() type safe,
>    if we have a recent gcc */

It just so happens that the trick for type safety fixes the problem for
recent GCC by having an explicit cast.

> So, maybe the way to satisfy everyone would be:
>
> notmuch_message_t *tmp_message = message;
> talloc_steal(notmuch, tmp_message);
> return(tmp_message);
>
> Or alternatively,
>
> #if (__GNUC__ >= 3)
>        return talloc_steal (notmuch, message);
> #else
>        return (notmuch_message_t*) talloc_steal (notmuch, message);
> #fi
>
>
> Of course I'm happy either way :)

I'm throwing in a third alternative below. Does it work for you? I think
it's both prettier and uglier than the above at the same time! ;)

A middle ground would be to change the callers to use
"notmuch_talloc_steal", and just #define notmuch_talloc_steal
talloc_steal if __GNUC__ >= 3.

One could argue upstream talloc should have this, but OTOH it's a C
library.

BR,
Jani.


diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index ea836f7..83b46e8 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -499,4 +499,22 @@ _notmuch_filenames_create (const void *ctx,
 
 NOTMUCH_END_DECLS
 
+#ifdef __cplusplus
+/* Implicit typecast from 'void *' to 'T *' is okay in C, but not in
+ * C++. In talloc_steal, an explicit cast is provided for type safety
+ * in some GCC versions. Otherwise, a cast is required. Provide a
+ * template function for this to maintain type safety, and redefine
+ * talloc_steal to use it.
+ */
+#if !(__GNUC__ >= 3)
+template <class T>
+T *notmuch_talloc_steal(const void *new_ctx, const T *ptr)
+{
+    return static_cast<T*>(talloc_steal(new_ctx, ptr));
+}
+#undef talloc_steal
+#define talloc_steal notmuch_talloc_steal
+#endif
+#endif
+
 #endif


More information about the notmuch mailing list