https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70318

            Bug ID: 70318
           Summary: `std::sqrt<int>(int)` Produces -Wfloat-conversion
                    Warning, Erroneous After C++11.
           Product: gcc
           Version: 5.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ian at geometrian dot com
  Target Milestone: ---

Created attachment 38032
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38032&action=edit
Sample given in text, as a file.

As required by the C++ standard, after C++11, the `std::sqrt` function in
`<cmath>` is required to have "A set of overloads or a function template
accepting an argument of any integral type."

Consider the following command-line tool for computing integer-square root:

//Compile like so: g++ isqrt.cpp -std=c++11 -Wfloat-conversion -o isqrt
#include <cmath>
#include <iostream>
int main(int argc, char* argv[]) {
        if (argc!=2) {
                std::cout << "Usage: \"./isqrt [integer]\"" << std::endl;
                return -1;
        } else {
                int arg = atoi(argv[1]);
                int isqrt = std::sqrt<int>(arg);
                std::cout << isqrt << std::endl;
                return isqrt;
        }
}

When compiling as the comment says, a warning is produced:

isqrt.cpp: In function ‘int main(int, char**)’:
isqrt.cpp:10:33: warning: conversion to ‘int’ from
‘__gnu_cxx::__enable_if<true, double>::__type {aka double}’ may alter its value
[-Wfloat-conversion]
   int isqrt = std::sqrt<int>(arg);
                                 ^

Internally, the argument is indeed converted to `double`, before doing the
square root with `double`s (at it should be).  However, since the overload is
required to exist separately and explicitly (and it evidently doesn't), I think
this warning is erroneous.

For your convenience, my sample is also attached as a file.

Reply via email to