it-roy-ru.com

Предупреждение: переполнение при неявном преобразовании констант

В следующей программе строка 5 выдает предупреждение о переполнении, как и ожидалось, но, что удивительно, строка 4 не выдает никакого предупреждения в GCC: http://www.ideone.com/U0BXn

int main()
{
    int i = 256;
    char c1 = i;    //line 4
    char c2 = 256;  //line 5
    return 0;
}

Я думал, что обе строки должны давать предупреждение overflow. Или мне чего-то не хватает?


Тема, которая привела меня к этому эксперименту, такова: проверка типа typedef?

Там я сказал следующее (которое я удалил из своего ответа, потому что, когда я его запустил, он не появился так, как я ожидал):

//However, you'll get warning for this case:

typedef int  T1;
typedef char T2;

T1 x = 256;     
T2 y = x; //possible overflow warning! (but it doesn't give warning :()
13
Nawaz

-Wall не включает много опций. -Wconversion является одним из них и предупреждает о поведении, которое вас интересует.

Смотрите http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

11
Crazy Eddie

В общем случае присвоения значения int объекту char компилятор не знает, находится ли int вне диапазона char.

Посмотрите на фактическое предупреждение более внимательно:

warning: overflow in implicit constant conversion

Именно в этом конкретном случае, когда константа преобразуется в char, компилятор может предупредить вас. Аналогично, если вы изменили объявление i на const:

const int i = 256;

вы также получите предупреждение, потому что значение, присваиваемое c2, является константным выражением.

Также обратите внимание, что предупреждение несколько вводит в заблуждение, поскольку преобразование технически не «переполнено». Арифметическое переполнение приводит к неопределенному поведению в C++. Сужающее преобразование (например, int в char, если int имеет больший диапазон, чем char) приводит к некоторому преобразованию, определяемому реализацией.

8
James McNellis

Ну, строка 5 - это очевидная ошибка, которую может видеть любой компилятор, и всегда ошибка. Строка 4 потребует, по крайней мере, некоторые анализа потока данных, чтобы обнаружить ошибку. Возможно, это не сделано с настройками, используемыми на сайте, или, возможно, авторы компилятора не сочли это достаточно важным, чтобы понять это.

1
Bo Persson

После GCC 4.3 семантика -Wconversion была обновлена ​​для обнаружения неявных преобразований, которые могут изменить значение, но вы также должны включить -Wsign-conversion, потому что в противном случае вы не получите предупреждение для кода, который может изменить знак числа из-за принуждение между подписанным и неподписанным типами.

Вопреки тому, что говорит Сумасшедший Эдди, до GCC 4.3 (который еще не был выпущен в то время) -Wconversion в общем случае не проверял проблемы, вызванные неявным преобразованием типов и тому подобным. Скорее, он проверял, будет ли ваша программа вести себя не так, как если бы она использовала прототипы функций K & R в старом стиле.

Это не только означало, что оно не давало предупреждения о всех неявных проблемах преобразования/приведения типов, но также означало, что хороший код выдавал ненужное предупреждение. И, конечно, вы не получите ошибки с g++, потому что такие прототипы не являются C++ в любом случае.

0
Anonymous