Search code examples
c++typescastingg++narrowing

float to double misinterpretation??? g++


for some reason I'm getting the following warning

filename.cpp:99:53: warning: narrowing conversion of ‘sin(((double)theta))’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]
filename.cpp:99:66: warning: narrowing conversion of ‘cos(((double)theta))’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]

which makes it sounds like it's trying to use the 'double cos(double)' etc. instead of 'float cos(float)' etc. I keep trying to think of more ways to suggest this to the compiler but am not getting anywhere. What can I do to resolve this?

void foo(float theta)
{
    theta = (float)M_PI*theta/180.0f;
    MyClass variable = { 1.0f,    0.0f,         0.0f,   0.0f,
                         0.0f, cos(theta), -sin(theta), 0.0f,
                         0.0f, sin(theta),  cos(theta), 0.0f,
                         0.0f,     0.0f,        0.0f,   1.0f };
    bob = variable;
}

Thanks


Edit: changing it to this makes the warnings go away, but I'd still rather know what the problem is

float C = cos(theta), S = sin(theta);
MyClass variable = { 1.0f,    0.0f,         0.0f,   0.0f,
                 0.0f, C, -S, 0.0f,
                 0.0f, S,  C, 0.0f,
                 0.0f,     0.0f,        0.0f,   1.0f };

Solution

  • You need to use std::sin and std::cos in place of sin and cos so that you will obtain the properly overloaded versions. You can see the difference live:

    MyClass variable = { 1.0f,    0.0f,         0.0f,   0.0f,
                         0.0f, std::cos(theta), -std::sin(theta), 0.0f,
                         0.0f, std::sin(theta),  std::cos(theta), 0.0f,
                         0.0f,     0.0f,        0.0f,   1.0f };
    

    It is unspecified behavior whether the functions from C libraries are first declared in the global namespace the C++ draft standard section 17.6.1.2 Headers paragraph 4 says(emphasis mine):

    Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).

    so in the case where the C library functions were in the global namespace you would be getting the version of cos and sin that only takes double which is consistent with the behavior we are seeing.