I have a comparator function I use with qsort
to sort an array of char*
(i.e., char**
), which compiles with current versions of Clang and GCC without giving errors or warnings:
static int
comparator(const void* a, const void* b)
{
#ifdef __cplusplus
auto a_recast = const_cast<void *>(a);
auto b_recast = const_cast<void *>(b);
auto a_rerecast = reinterpret_cast<char **>(a_recast);
auto b_rerecast = reinterpret_cast<char **>(b_recast);
auto a_rererecast = const_cast<const char **>(a_rerecast);
auto b_rererecast = const_cast<const char **>(b_rerecast);
return std::strcmp(*a_rererecast, *b_rererecast);
#else
return strcmp(*(const char**) a, *(const char**) b);
#endif
}
It compiles conditionally, that is, depending on whether a C or C++ compiler is used, one or the other block of code is compiled.
I offer both blocks, because this is part of a program that can be compiled alone in C, or in a larger suite of tools compiled with a C++ toolkit.
My question is about the work I had to do to in the C++ block, where I strip const
, recast to char **
, and reapply const
.
Is there a simpler or cleaner way to do this C++-style casting, which generates the correct end results and does not result in warnings about C-style casting?
Clang, in particular, is chatty with warnings about old C-style casts, and I like my build logs to be clean, where fixes are realistic.
I also like the code to be clear and easy to and maintain. I'd also like to inline
this code, which would probably be easier for the compiler if the comparator function is smaller.
If I'm doing the correct work, that's fine, but if there are better ways, I'd be interested to learn them. Thanks for your advice.
<string.h>
? As an aside, you would usestd::sort()
in C++ because it's far more efficient and type-safe. \$\endgroup\$#ifdef __cplusplus
is something you'd use in a header so that you can link C code with C++ code. I'd recommend you write this as C, and declare it with C linkage (i.e.extern "C"
, when__cplusplus
is defined). \$\endgroup\$