У меня есть эта функция для создания вектора из полярной нотации, использующего в нем фигурный инициализатор:
// Constructs a 2D vector from XY-coordinates.
inline vector2(float x, float y) : x_(x), y_(y) { }
// Constructs a 2D vector from polar coordinates
static vector2 polar(float r, float phi) {
return {r * cos(phi), r * sin(phi)};
}
В MSVS все выглядит нормально, но компилятор g ++ показывает предупреждения, которые для меня кажутся довольно странными:
vector2.h:37:23: warning: narrowing conversion of ‘(((double)r) * cos(((double)phi)))’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]
return {r * cos(phi), r * sin(phi)};
~~^~~~~~~~~~
Если я использую конструктор, предупреждение исчезает:
// Constructs a 2D vector from polar coordinates
static vector2 polar(float r, float phi) {
return vector2(r * cos(phi), r * sin(phi));
}
Почему появляется это предупреждение? Означает ли это, что скомпилированная программа выполнит ненужное преобразование из float
в double
и обратно в float
?
ОБНОВЛЕНИЕ Вот минимальный воспроизводимый пример
#include <iostream>
#include <cmath>
using std::cout;
using std::endl;
class Pair {
public:
float x_;
float y_;
inline Pair(float x, float y) : x_(x), y_(y) {};
};
Pair braced(float a) {
return {a * 2, cos(a) * 3};
}
Pair constr(float a) {
return Pair(a * 2, cos(a) * 3);
}
Pair stdbraced(float a) {
return {a * 2, std::cos(a) * 3};
}
Pair stdconstr(float a) {
return Pair(a * 2, std::cos(a) * 3);
}
int main() {
float x = 2.0;
auto a = braced(x);
cout << a.x_ << ' ' << a.y_ << endl;
auto b = constr(x);
cout << b.x_ << ' ' << b.y_ << endl;
auto c = stdbraced(x);
cout << c.x_ << ' ' << c.y_ << endl;
auto d = stdconstr(x);
cout << d.x_ << ' ' << d.y_ << endl;
}
Вывод g++ test.cpp -o test
:
test.cpp: In function ‘Pair braced(float)’:
test.cpp:15:27: warning: narrowing conversion of ‘(cos(((double)a)) * (double)3)’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]
return {a*2,cos(a)*3};
~~~~~~^~
Так что использование std::cos
помогает. Но главный вопрос остается (и меня беспокоит) - почему предупреждение появляется только при использовании брекет-инициализации?