Pregunta

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!]

¿Fue útil?

Solución

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.

Otros consejos

You want the quote from the FDIS?

Last paragraph of 26.8:

Moreover, there shall be additional overloads sufficient to ensure:

  1. If any argument corresponding to a double parameter has type long double, then all arguments corresponding to double parameters are effectively cast to long double.

  2. Otherwise, if any argument corresponding to a double parameter has type double or an integer type, then all arguments corresponding to double parameters are effectively cast to double.

  3. Otherwise, all arguments corresponding to double parameters are effectively cast to float.

In this case it must be point 2 that applies.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top