This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Allow __cplusplus=199711L to work with Solaris 2 headers


On 14 March 2011 20:23, Rainer Orth wrote:
>
> As expected, things broke left and right, but I've now investigated the
> failure modes, worked around them (manually for the moment, fixincludes
> fixes to follow once the analysis is finished) and managed to get C++
> testresults with only four regressions which are due to a g++ bug.

Fantastic, thanks for working on this, Rainer!

> /vol/gcc/obj/gcc-4.6.0-20110311/11-gcc-cplusplus/i386-pc-solaris2.11/libstdc++-v3/include/cmath:82:3: error: redefinition of 'double std::abs(double)'
>
> ?inline double
> ?abs(double __x)
> ?{ return __builtin_fabs(__x); }
>
> /usr/include/iso/math_iso.h:159:16: error: 'double std::abs(double)' previously defined here
>
> ? ? ? ?inline double abs(double __X) { return fabs(__X); }
>
> There are many more of those. ?To avoid them, I've changed
> <iso/math_iso.h> to read
>
> -#if __cplusplus >= 199711L
> +#if __cplusplus >= 199711L && !defined(__GNUG__)
>
> While this certainly works, I'm unclear if the Solaris definition is
> actually wrong (I don't think so, but am ignorant of C++). ?Depending on
> the analysis, I'll try to get necessary fixes into Solaris 11, and have
> some hope of success since I've got decent contacts into Solaris
> engineering. ?This is one of the reasons for posting this so shortly
> after the discussions in the PR.

C++ defines additional overloads of those C library functions, so as
well as fabs/fabsf/fabsl we have overloaded abs() taking the same
arguments.

The Solaris headers think that when included by a C++ compiler they
should define those overloads. The libstdc++ headers think that the C
library won't provide them, so it provides them.  Neither is "wrong"
it's just a mistaken assumption.

IMHO the right fix would be for libstdc++ to be aware that it's got a
cooperative C library that want to help and provide some of those
overloads.  I believe the original libstdc++ design was that one of
the libstdc++-v3/include/c_* directories would contain headers
designed to work with a cooperative C library, but I don't know what
the status of those directories is.


> Next failure:
>
> In file included from /usr/include/stdlib.h:32:0,
> ? ? ? ? ? ? ? ? from /vol/gcc/obj/gcc-4.6.0-20110311/11-gcc-cplusplus/i386-pc-solaris2.11/libstdc++-v3/include/cstdlib:66,
> ? ? ? ? ? ? ? ? from /vol/gcc/src/hg/trunk/solaris/libstdc++-v3/include/precompiled/stdc++.h:48:
> /usr/include/iso/stdlib_iso.h: At global scope:
> /usr/include/iso/stdlib_iso.h:129:14: error: previous declaration of 'void* std::bsearch(const void*, const void*, std::size_t, std::size_t, int (*)(const void*, const void*))' with 'C' linkage
> /usr/include/iso/stdlib_iso.h:134:38: error: conflicts with new declaration with 'C++' linkage
>
> extern void *bsearch(const void *, const void *, size_t, size_t,
> ? ? ? ?int (*)(const void *, const void *));
> #if __cplusplus >= 199711L
> extern "C++" {
> ? ? ? ?void *bsearch(const void *, const void *, size_t, size_t,
> ? ? ? ? ? ? ? ?int (*)(const void *, const void *));
> }
> #endif /* __cplusplus >= 199711L */
>
> One more, can again be avoided by adding && !defined(__GNUG__)

Those overloads do need to be disabled conditionally, due to PR 2316.
G++ doesn't allow overloading on language linkage.


> In file included from /vol/gcc/src/hg/trunk/solaris/libstdc++-v3/include/precompiled/stdc++.h:48:0:
> /vol/gcc/obj/gcc-4.6.0-20110311/11-gcc-cplusplus/i386-pc-solaris2.11/libstdc++-v3/include/cstdlib: In function 'long int std::abs(long int)':
> /vol/gcc/obj/gcc-4.6.0-20110311/11-gcc-cplusplus/i386-pc-solaris2.11/libstdc++-v3/include/cstdlib:139:3: error: redefinition of 'long int std::abs(long int)'
>
> ?inline long
> ?abs(long __i) { return labs(__i); }
>
> /usr/include/iso/stdlib_iso.h:170:16: error: 'long int std::abs(long int)' previously defined here
>
> #if __cplusplus >= 199711L
> extern "C++" {
> ? ? ? ?inline long ? abs(long _l) { return labs(_l); }
> ? ? ? ?inline ldiv_t div(long _l1, long _l2) { return ldiv(_l1, _l2); }
> }
> #endif /* __cplusplus */
>
> I don't fully understand the issue: is this due to the redefinition, or
> would a redefinition with matching formal parameter names (or without
> them) work? ?(I haven't tried.)

As above, this is because the native libc is trying to be helpful, but
libstdc++ assumes libc is never helpful, so they both try to define
the same functions.

The struct tm ABI breakage and some of the other issues are more
serious, but the various redefinitions should be simple to fix by
teaching libstdc++ not to define them when the native libc does,
although the other v3 maintainers might prefer a different solution.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]