3

I'm often using the wrong literals in expressions, e.g. dividing a float by an int, like this:

float f = read_f();
float g = f / 2;

I believe that the compiler will in this case first convert the int literal (2) to float, and then apply the division operator. GCC and Clang have always let stuff like that pass, but Visual C++ warns about an implicit conversion. So I have to write it like this:

float f = read_f();
float g = f / 2.0f;

That got me wondering: Should I always use the appropriate literals for float, double, long etc.? I normally use int literals whenever I can get away with it, but I'm not sure if that's actually a good idea.

  • Is this a likely cause of subtle errors?
  • Is this only an issue for expressions or also for function parameters?
  • Are there warning levels for GCC or Clang that warn about such implicit conversions?
  • How about unsigned int, long int etc?
futlib
  • 8,258
  • 13
  • 40
  • 55
  • 2
    Your could should always show intention. If you intended to do an integer divide, use an integer literal etc. so people reading the code afterward can reason better about your intentions. – PlasmaHH Oct 30 '12 at 16:31
  • There can be performance hits for using the 2 instead of 2.0f. see [here](http://stackoverflow.com/questions/9314534/why-does-changing-0-1f-to-0-slow-down-performance-by-10x). – andre Oct 30 '12 at 16:35
  • 2
    @ahenderson: if the compiler leaves the conversion of 2 to 2.0f until runtime, there are bigger concerns about the efficiency of the code produced by the compiler than just this little bit. – Jonathan Leffler Oct 30 '12 at 16:37
  • @jozefg: If typing three characters is a problem for you, you're probably in the wrong business. – Lightness Races in Orbit Oct 30 '12 at 16:40
  • You can persuade GCC to complain about such conversions if you try hard enough, but you have to be trying quite hard. From GCC 4.7.1, `gcc --help=warnings`, you can use `-Wconversion` _Warn for implicit type conversions that may change a value_ and `-Wconversion-extra` _Warn about most implicit conversions_. – Jonathan Leffler Oct 30 '12 at 16:40
  • Oops my bad. My last link was only for values close to zero. But in general just type what you mean make life simple for anyone reading your code in the future. – andre Oct 30 '12 at 16:43

2 Answers2

2

You should always explicitly indicate the type of literal that you intend to use. This will prevent problems when for example this sort of code:

float foo = 9.0f;
float bar = foo / 2;

changes to the following, truncating the result:

int foo = 9;
float bar = foo / 2;

It's a concern with function parameters as well when you have overloading and templates involved.

I know gcc has -Wconversion but I can't recall everything that it covers.

For integer values that fit in int I usually don't qualify those for long or unsigned as there is usually much less chance there for subtle bugs.

Mark B
  • 95,107
  • 10
  • 109
  • 188
1

There's pretty much never an absolutely correct answer to a "should" question. Who's going to use this code, and for what? That's relevant here. But also, particularly for anything to do with floats, it's good to get into the habit of specifying exactly the operations you require. float*float is done in single-precision. anything with a double is done double-precision, 2 gets converted to a double so you're specifying different operations here.

The best answer here is What Every Computer Scientist Should Know About Floating-Point Arithmetic. I'd say don't tl;dr it, there are no simple answers with floating point.

jthill
  • 55,082
  • 5
  • 77
  • 137