Hi, I have been wondering whether it makes sense to add a small utility trying to make typecasts in C as type-safe as possible.
The problem is that typecasts are sometimes unavoidable. For an example, let's take a look at the following snippet using Gnulib's xlist module: struct foo { int bar; }; gl_list_t list = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, NULL, false); struct foo foo = { .bar = 1 }; gl_list_add_last (list, &foo); gl_list_iterator_t i = gl_list_iterator (list); struct foo *elt; while (gl_list_iterator_next (&i, (const void **) &elt, NULL)) ++elt->bar; gl_list_iterator_free (&i); Here, the typecast '(const void **)' is needed as 'gl_list_iterator_next' expects an argument of that type and because 'struct foo **elt' is not implicitly convertible to 'const void **' (in fact, even not to 'void **'). The problem with this typecast is that the compiler wouldn't have complained if I had forgotten to write the address operator '&' before 'elt'. So what I have in mind are macros that do a type conversion from A to B and that signal an error on modern compilers if the input is not of type A. For this, the C11 construct _Generic can be used. The macros could look like CAST (<from-type>, <to-type>, <expr>) CVR_CAST (<type>, expr) /* removes cvr qualifier */ ADDRESS_CAST (<from-type>, <to-type>, expr) expanding, respectively, into _Generic ((<expr>), (<from-type>): ((<to-type>) (<expr>))) _Generic ((<expr>), (<type>): ((<type>) (<expr>)), (const <type>): ((<type> (<expr>)), (const volatile <type>): ((<type>) (<expr>)), ...) _Generic ((<expr>), (<from-type>): (((<to-type>) *) &(<expr>))) The names and the exact semantics and number of macros are, of course, debatable. Marc