My code is as follows:
#include <cmath>
#include <iostream>
float foo(float f) {
std::cout << "float\n";
return f;
}
double foo(double d) {
std::cout << "double\n";
return d;
}
int main() {
int i = 16;
// foo(i); // ambiguous call, of course
return (int) std::sqrt(i);
}
The call in the last line is not reported ambiguous even with -pedantic -std=c++98 -Wall -Wextra
, but it doesn't necessarily work at all in other compilers, for the same reason foo(i)
doesn't.
gcc adds the following to namespace std
:
template<typename _Tp>
inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
double>::__type
sqrt(_Tp __x)
{ return __builtin_sqrt(__x); }
That is, it adds inline double sqrt(X)
for all integer types X.
I appreciate g++ doing its best to help me out and all, but is there any (legitimate) way to make it diagnose the bug in my code?
[Edit: I'm using gcc 4.3.4, but if other versions of gcc can diagnose it then I'm interested in that fact too!]
This "helpful" Standard Library addition by GCC is non-conforming in C++03, according to
[lib.global.functions]/2:
A call to a global function signature [described in the Standard Library definition] behaves the same as if the implementation declares no additional global function signatures.
Which means that the implementation (gcc) is not permitted to add extra overloads (helpful or not), as long as they affect the observable behavior of the program.