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.
You want the quote from the FDIS?
Last paragraph of 26.8:
Moreover, there shall be additional overloads sufficient to ensure:
If any argument corresponding to a
double
parameter has typelong double
, then all arguments corresponding todouble
parameters are effectively cast tolong double
.Otherwise, if any argument corresponding to a
double
parameter has typedouble
or an integer type, then all arguments corresponding todouble
parameters are effectively cast todouble
.Otherwise, all arguments corresponding to
double
parameters are effectively cast tofloat
.
In this case it must be point 2 that applies.
精彩评论