Why don't g ++ or clang raise a warning when truncating a non-constant variable, assigning it to a smaller type variable?

Both clang 2.9 and g ++ 4.1.2 generate a warning when the variable x is declared constant in the code snippet below. However, when const is removed, as in the fragment, not one of the compilers generates a warning even when executed with the following parameters, which are the most stringent that I know: "-Wall -Wextra -pedantic -ansi"

Why do compilers not display and report the same warning, since x is not mutable and cannot be changed before type conversion?

#include <iostream>

int main(int argc, char **argv)
{
    unsigned int x = 1000;
    const unsigned char c = x;
    const unsigned int x_ = c;
    std::cout << "x=" << x << " x_=" << x_ << std::endl;
    return 0;
}

const unsigned int x = 1000; g++ ": , unsigned type" clang ": " const unsigned int "" const unsigned char " 1000 232 [-Wconstant-conversion]".

?

+3
3

GCC -Wconversion, . -Wall, . , .

+4

const, . , , . :

const unsigned int x = 1000;
const unsigned char c = x;

:

const unsigned char c = 1000;
+2

I ran gcc with -O3 -fdump-tree-vrp and what I see in the dump:

std::__ostream_insert<char, std::char_traits<char> > (&cout, &"x="[0], 2);
D.20752_20 = std::basic_ostream<char>::_M_insert<long unsigned int> (&cout, 1000);
std::__ostream_insert<char, std::char_traits<char> > (D.20752_20, &" x_="[0], 4);
D.20715_22 = std::basic_ostream<char>::_M_insert<long unsigned int> (D.20752_20, 232);

i.e. it just inserts constants 1000 and 232 into the cout statement!

If I run it with -O0, it does not reset anything, despite the switch -ftree-vrp and -ftree-ccp.

Gcc seems to be building constants before it can issue warnings ...

+1
source

All Articles