Почему g ++ или clang не выдают предупреждение при усечении неконстантной переменной, присваивая ее переменной меньшего типа? - PullRequest
3 голосов
/ 12 мая 2011

Оба clang 2.9 и g ++ 4.1.2 сгенерируют предупреждение, когда переменная x объявлена ​​постоянной в фрагменте кода ниже. Однако, когда const удаляется, как это было во фрагменте, ни один из компиляторов не генерирует предупреждение, даже когда выполняется со следующими параметрами, которые являются самыми строгими из известных мне: "-Wall -Wextra -pedantic -ansi «

Почему компиляторы не выводят и не выводят одно и то же предупреждение, поскольку x не является изменчивым и не может быть изменено до преобразования типа?

#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 ++ выдает сообщение " предупреждение: большое целое число неявно усекается до типа без знака " and clang " предупреждение: неявное преобразование из ' const unsigned int 'на' const unsigned char 'изменяет значение с 1000 на 232 [-Wconstant-преобразование]".

Есть ли способ автоматически обнаружить этот случай, не проверяя код вручную или не полагаясь на правильно спроектированные модульные тесты?

Ответы [ 3 ]

4 голосов
/ 12 мая 2011

Для GCC добавьте флаг -Wconversion, и вы получите желаемое предупреждение. Это не часть -Wall, так как так много кода просто игнорирует подобные вещи. Я всегда включаю его, так как в противном случае обнаруживаются трудности при отладке дефектов.

2 голосов
/ 12 мая 2011

Если это const, компилятор может увидеть его значение и предупредить об усечении. Если это не const, он не может, несмотря на инициализацию. Это:

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

эквивалентно:

const unsigned char c = 1000;
1 голос
/ 12 мая 2011

Я запустил gcc с -O3 -fdump-tree-vrp, и то, что я вижу в дампе:

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);

, то есть оно просто вставляет константы 1000 и 232 в операторе cout!

Если я запускаю его с -O0, он ничего не выгружает, несмотря на переключатели -ftree-vrp и -ftree-ccp.

Похоже, что gcc вставляет константы до того, как он может испуститьпредупреждения ...

...