Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to diagnose ambiguous call to sqrt(int&) in g++ 4.3.4

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

like image 452
Steve Jessop Avatar asked May 19 '11 09:05

Steve Jessop


2 Answers

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.

like image 92
decltype Avatar answered Sep 22 '22 19:09

decltype


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.

like image 32
Bo Persson Avatar answered Sep 25 '22 19:09

Bo Persson