Why doesn't clang warn of implicit conversion from double to int, but does 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 of implicit conversion (using -Wall and -std = C ++ 14) as follows:

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

which is normal. But there is no warning if the conversion occurs 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 does the compiler react differently in these situations?

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

Note 2: I tested it with many other versions of gcc, clang and icc thanks to the Compiler Explorer (gcc.godbolt.org). Thus, all verified versions of gcc (except for 5.x) and icc issued a warning. No version of clang did this.

+7
c ++ gcc c ++ 11 gcc-warning clang
source share
2 answers

Well, after reading this wonderful article entitled β€œWhat Every Programmer Should Know About Undefined Behavior”, especially part No. 3/3, in the LLVM Project Blog written by Chris Lattner, the main author of LLVM, I could better understand Clang's approach to handling Undefined Behavior .

So, to guarantee your strong appeal to optimize and save time - "maximum performance" -

Keep in mind that the compiler is limited by the lack of dynamic information and limited by the fact that it can without burning batches of compilation time.

Clang does not run all related Undefined default behavior checks,

Clang generates warnings for many Undefined behavior classes (including dereferencing of zero, oversized shifts, etc.), which are obvious in the code to catch some common errors.

instead, Clang and LLVM provide tools such as the Clang Static Analyzer , the Klee project , and -fcatch-undefined-behavior (now UndefinedBehaviorSanitizer - UBSan -) to avoid these possible errors.

When starting UBSan in the presented clang++ with the following argument -fsanitize=undefined error will be noted as follows:

runtime error: value 4.29497e+09 is outside the range of representable values of type 'int'

0
source share

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

Converting from long int to int instead can either work or may be undefined depending on the platform and value (the only guarantee is that int no bigger than long int , but they can be the same size).

In other words, conversion problems between integer types are random implementation artifacts, not design decisions. A warning about them is better, especially if it can be detected at compile time , because of these limitations, something is not working.

Note that even converting from double to int is legal and well-defined (if done within the boundaries), and implementation is not required to warn about this, even when loss of accuracy can be seen at compile time. Compilers that warn too much, even when usage can be significant, can be a problem (you just turn off warnings or get even worse the habit of accepting an unclean build as usual).

These implicit conversion rules can add up to other C ++ wrinkles that become really weird and difficult to justify for behaviors such as:

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

Do not try to use too much logic with C ++. Reading characteristics work better.

+3
source share

All Articles