Question

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 };
Was it helpful?

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.

OTHER TIPS

Looks like you are using C verison of sin/cos. It is difficult to say why without additional info, but fix could be to use C functions sinf/cosf or make sure C++ funcitons are used by std::sin() for example.

The compiler is complaining that you're using a float where it's expecting a double. You can either cast each use explicitly or just create a local double.

I'd rewrite your example as follows:

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

The cos and sin in the cmath library accepts a double as a parameter. The warning is trying to tell you that you are giving it a float and it will have to convert it to a double

The std version of the functions are overloaded, but if you want to use them you will have to call them with their namespace like so std::cos

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top