On Solaris 10, with cc and CC as compilers, I get this compilation error: "../gllib/stdlib.h", line 1406: Error: Cannot return extern "C" void(*)(void*,unsigned,unsigned,extern "C" int(*)(const void*,const void*,void*),void*) from a function that should return void(*)(void*,unsigned,unsigned,int(*)(const void*,const void*,void*),void*).
Apparently this compiler is picky regarding C linkage vs. C++ linkage of function types. This patch fixes it. 2021-12-24 Bruno Haible <br...@clisp.org> qsort_r: Fix compilation error with SunPRO C++ on Solaris 10. * lib/stdlib.in.h (_gl_qsort_r_compar_fn): New type. (qsort_r): Use it. * tests/test-stdlib-c++.cc (qsort_r): Don't test with SunPRO C++. diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 0855112d1..cb99492b3 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -828,29 +828,35 @@ _GL_CXXALIASWARN (putenv); /* Sort an array of NMEMB elements, starting at address BASE, each element occupying SIZE bytes, in ascending order according to the comparison function COMPARE. */ +# ifdef __cplusplus +extern "C" { +# endif +# if !GNULIB_defined_qsort_r_fn_types +typedef int (*_gl_qsort_r_compar_fn) (void const *, void const *, void *); +# define GNULIB_defined_qsort_r_fn_types 1 +# endif +# ifdef __cplusplus +} +# endif # if @REPLACE_QSORT_R@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef qsort_r # define qsort_r rpl_qsort_r # endif _GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, - int (*compare) (void const *, void const *, - void *), + _gl_qsort_r_compar_fn compare, void *arg) _GL_ARG_NONNULL ((1, 4))); _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, - int (*compare) (void const *, void const *, - void *), + _gl_qsort_r_compar_fn compare, void *arg)); # else # if !@HAVE_QSORT_R@ _GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, - int (*compare) (void const *, void const *, - void *), + _gl_qsort_r_compar_fn compare, void *arg) _GL_ARG_NONNULL ((1, 4))); # endif _GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, - int (*compare) (void const *, void const *, - void *), + _gl_qsort_r_compar_fn compare, void *arg)); # endif _GL_CXXALIASWARN (qsort_r); diff --git a/tests/test-stdlib-c++.cc b/tests/test-stdlib-c++.cc index 207944528..c16c8a809 100644 --- a/tests/test-stdlib-c++.cc +++ b/tests/test-stdlib-c++.cc @@ -114,7 +114,7 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::ptsname_r, int, (int, char *, size_t)); SIGNATURE_CHECK (GNULIB_NAMESPACE::putenv, int, (char *)); #endif -#if GNULIB_TEST_QSORT_R +#if GNULIB_TEST_QSORT_R && !defined __SUNPRO_CC SIGNATURE_CHECK (GNULIB_NAMESPACE::qsort_r, void, (void *, size_t, size_t, int (*) (void const *, void const *, void *), void *));