Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't clang warn about implicit conversion from double to int, but do it when from long to int?

In the following code:

#include <iostream>
int main()
{
  const long l = 4294967296;
  int i = l;
  return i; //just to silence the compiler
}

the compiler warns about implicit conversion (using -Wall and -std=c++14) as following:

warning: implicit conversion from 'const long' to 'int' changes value from 4294967296 to 0 [-Wconstant-conversion]

which is ok. But there is no warning if the conversion is from double to int, as in the following code:

#include <iostream>
int main()
{
  const double d = 4294967296.0;
  int i = d;
  return i; //just to silence the compiler
}

Why the compiler reacts differently in these situations?

Note 1: clang version is 3.6.2-svn240577-1~exp1

Note 2: I've tested it with many others versions of gcc, clang and icc thanks to Compiler Explorer (gcc.godbolt.org). So all tested versions of gcc (with exception of 5.x) and icc threw the warning. No clang version did it.

like image 668
Vinicius Sa Avatar asked Sep 02 '16 00:09

Vinicius Sa


1 Answers

The conversion from double to an integer type changes the value "by design" (think to 3.141592654 converted to an int).

The conversion from long int to int instead may or work or may be undefined behavior depending on the platform and on the value (the only guarantee is that an int is not bigger than a long int, but they may be the same size).

In other words the problems in the conversions between integer types are incidental artifacts of the implementation, not by-design decisions. Warning about them is better especially if it can be detected at compile time that something doesn't work because of those limitations.

Note also that even conversion from double to int is legal and well defined (if done within boundaries) and an implementation is not required to warn about it even when the loss of precision can be seen at compile time. Compilers that warn too much even when the use could be meaningful can be a problem (you just disable warnings or even worse get the habit of accepting a non-clean build as normal).

These implicit conversion rules may add up with other C++ wrinkles getting to truly odd-looking and hard to justify behaviors like:

std::string s;
s = 3.141592654; // No warnings, no errors (last time I checked)

Don't try to use too much logic with C++. Reading specs works better.

like image 106
6502 Avatar answered Nov 09 '22 04:11

6502