https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89855
Bug ID: 89855 Summary: Inconsistent global namespace overload sets from #include <cmath> Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- In the following, I use the function "log" as an example, but this applies to effectively everything in cmath, and ::abs in cstdlib. The C standard library <math.h> defines: double log(double); libstdc++ <cmath> includes libc <math.h>, and then does: namespace std { using ::log; float log(float); long double log(long double); double log(Any-Integral-Type); } libstdc++ <math.h> does: #include <cmath> using std::log; This has the unfortunate effect that code which includes <cmath> and uses global ::log ends up accidentally calling the double overload of log. E.g., a program like this: #include <cmath> float foo(float f) { return log(f); } Granted, the above code is non-portable, and may not even compile on some other standards-conforming implementation. I do not believe this is a standards-compliance issue in libstdc++ -- the header <cstdlib> is permitted, but not required to define ::log. However, IMO, it's a *QoI* bug that libstdc++ doesn't provide consistent overload sets. The problem is that the behavior of the above code _very subtly_ changes upon adding or removing an #include which transitively has an "#include <math.h>" in it. This can cause extremely surprising bugs. I'd suggest that either #include <cmath> ought to define NO global ::log function at all (thus, the above program fails to compile), or it should define the entire overload set for ::log. No partial overload sets. Since not defining ::log from cmath is effectively impossible, given the current interfaces between libc and libstdc++, I think the latter is what should be done. Concretely, that simply means moving all of the global namespace "using std::log" (etc.) statements from libstdc++'s <math.h> into libstdc++'s <cmath>. (I would also suggest that it'd be reasonable for a future C++ standard to require that. E.g., it could say something like: While <math.h> may or may not declare functions in ::std::, and <cmath> may or may not declare functions in ::, if they _do_ declare any such name, they must define the complete set of required overloads, not a subset.)