Prevent implicit conversions from float to double in C ++

Basically, if I want something like this,

double b = sin(2.2); 

but accidentally write something like this,

 double b = sin(2.2f); 

there is no error message or even warning, although this clearly leads to a different, inaccurate and therefore incorrect result. This type of error could have been prevented by forcing the compiler not to do any implicit float conversions to double. Is there a way to achieve this, whether using a compilation switch (preferably in Visual Studio), some smart macros, or a class that behaves like float / double variables and declares its own operators?

Edit: I am also interested in solving similar problems using operators (for example, double b = 2.2f * 2.2f) or assignments (double b = 2.2f).

+6
source share
4 answers

You can use the type_assert utility.

Example:

 #include <cmath> #include <type_traits> template<typename T, typename U> const U& type_assert(const U& u) { static_assert(std::is_same<T, U>::value, "..."); return u; } int main() { double t = type_assert<double>(std::sin(2.2f)); } 

If the expected type is different, then it will give you a compiler error. Most likely, the compiler could optimize this if it passes, although at least it happened in my case with -O3 .

+5
source

You can make the sin(float) call ambiguous by specifying something like

 double sin(float x) { abort(); } 

Then calling sin on a float will give you a compile-time error. This works because in the cmath header std::sin is an overloaded function with options float sin(float) , double sin(double) and long double sin(long double) . The compiler cannot know if you want ::sin(float) or std::sin(float) , so it gets confused.

I would not recommend leaving such things in my codebase, but it can be useful if you are trying to find all errors like this and fix them.

+4
source

Something like that?

 class MyDouble{ public: MyDouble(float _f) {throw "only use double!";} MyDouble(double _d) : m_data(_d) {} operator float() const {throw "conversion to float occurred!";} operator double() const {return m_data;} private: double m_data; }; 

but yes, you will have to start using this class in your math function calls, making it very ugly:

 MyDouble d(3.2); sin(d); // or... cos(MyDouble(2.3)); 

UPDATE - an example of operator implementation (a binary operator, as unary, must be part of the class):

 MyDouble operator+(const & MyDouble _lhs, const & MyDouble _rhs){ MyDouble rez(_lhs); rez += _rhs; return rez; } 

Of course, you do not need to implement it this way (using the shortcut operator+= ), but this simplifies the work with the code

+2
source

I only realized that you are using a Microsoft product, but I will leave this answer as it can help someone else.

Have you looked at the compiler keys? I guess there is a similar option.

OMG! I was just looking for help in Visual Studio settings and alerts! ( link )

I am so sorry! I did not know! This is one of the most useful lists of options and switches I've ever seen! Even more ironically, they began to clear StackOverflow for answers and links here.

But I found some clues:

Compiler Warning (Levels 3 and 4) C4244 - Conversion from "type1" to "type2" conversion, possible data loss

Used this way:

 // Enable this to find unintended double to float conversions. // warning C4244: 'initializing' : conversion from 'double' to 'float', possible loss of data #pragma warning(3 : 4244) 

Switches

GCC / g ++ (

Why not tell the compiler when you accidentally do this?

From the g ++ / gcc man page:

 -Wdouble-promotion (C, C++, Objective-C and Objective-C++ only) * Give a warning when a value of type "float" is implicitly promoted to "double". ... some verbage clipped ... * It is easy to accidentally do computations with "double" because floating-point literals are implicitly of type "double". 

Adding -Wdouble-promotion to your CXXFLAGS should contain compilation warnings.

There is also -fsingle-precision-constant , which prohibits the implicit conversion of floating-point numbers to double.

+2
source

Source: https://habr.com/ru/post/971505/


All Articles