Bug #15209
openFix C++ math function visibility
0%
Description
One of the more common issues building third-party packages on illumos are failures related to the visibility of math functions in C++ code. In pkgsrc we already have over 50 patches for errors of the type:
error: call of overloaded 'abs(long long int&)' is ambiguous
or similar, for software that builds fine unmodified on Linux, NetBSD, macOS, etc.
In both /usr/include/iso/math_iso.h
and /usr/include/iso/stdlib_iso.h
there are a large number of math function prototypes and inline functions that are always defined for C++ code, whereas other OS do not have them. For example in /usr/include/iso/stdlib_iso.h
:
#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 */
This exposes an additional abs()
prototype alongside the regular abs(3C)
prototype, resulting in the GCC error for any C++ use of abs()
which does not match exactly to one of the available prototypes. It is unclear at this time why they were added, but a clue may be found in the fact that elsewhere in stdlib_iso.h
there is an additional limit on the Sun Studio compiler:
#if __cplusplus >= 199711L && defined(__SUNPRO_CC)
extern "C++" {
void *bsearch(const void *, const void *, size_t, size_t,
int (*)(const void *, const void *));
}
#endif /* __cplusplus >= 199711L && defined(__SUNPRO_CC) */
My suspicion is that these were added to aid the Sun Studio compiler of the day, but other sections were not correctly limited to Sun Studio, and so have been breaking GCC ever since.
In my testing, applying the following patches fixes builds that previously failed with math-related "ambiguous" errors:
--- /usr/include/iso/math_iso.h Thu Aug 26 05:36:42 2021
+++ /usr/include/iso/math_iso.h Mon Nov 28 11:16:12 2022
@@ -99,7 +99,7 @@
#pragma no_side_effect(ceil, fabs, floor, fmod)
#endif
-#if __cplusplus >= 199711L
+#if __cplusplus >= 199711L && defined(__SUNPRO_CC)
extern float __acosf(float);
extern float __asinf(float);
extern float __atanf(float);
--- /usr/include/iso/stdlib_iso.h Thu Aug 26 05:36:42 2021
+++ /usr/include/iso/stdlib_iso.h Mon Nov 28 11:13:36 2022
@@ -162,7 +162,7 @@
extern size_t wcstombs(char *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
size_t);
-#if __cplusplus >= 199711L
+#if __cplusplus >= 199711L && defined(__SUNPRO_CC)
extern "C++" {
inline long abs(long _l) { return labs(_l); }
inline ldiv_t div(long _l1, long _l2) { return ldiv(_l1, _l2); }
I'll test these patches across bulk builds to ensure there is no fallout, as well as rebuilding GCC with them applied to ensure there is no change in behaviour.
One point up for debate is whether we should just remove them completely, or if we still want to retain support for Sun Studio.
Related issues
Updated by Jonathan Perkin about 1 year ago
Jonathan Perkin wrote:
I'll test these patches across bulk builds to ensure there is no fallout, as well as rebuilding GCC with them applied to ensure there is no change in behaviour.
While this fixed a couple of issues, it also causes some, notably during the build of GCC, so I'll need to dig further for a more correct fix.
In case anyone is interested in a small test case for this, the following (obviously silly) program builds fine across Linux, NetBSD, and macOS, using various versions of GCC and clang:
#include <cmath>
int
main()
{
double r = log(1);
}
On illumos however:
test.cc: In function 'int main()': test.cc:6:23: error: call of overloaded 'log(int)' is ambiguous 6 | double r = log(1); | ~~~^~~ In file included from /usr/include/math.h:35, from /opt/tools/gcc12/include/c++/12.2.0/cmath:45, from test.cc:1: /usr/include/iso/math_iso.h:215:28: note: candidate: 'long double std::log(long double)' 215 | inline long double log(long double __X) { return __logl(__X); } | ^~~ /usr/include/iso/math_iso.h:172:22: note: candidate: 'float std::log(float)' 172 | inline float log(float __X) { return __logf(__X); } | ^~~ /usr/include/iso/math_iso.h:72:15: note: candidate: 'double std::log(double)' 72 | extern double log(double); | ^~~
Updated by Andy Fiddaman 4 months ago
- Related to Bug #5290: int64_t issues for abs() with c++ out of stdlib.h added