Ответ 1
-Wall
не содержит много параметров. -Wconversion
является одним из них и предупреждает о поведении, которое вас интересует.
В следующей программе строка 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;
}
Я думал, что обе строки должны давать предупреждение о переполнении. Или что-то мне не хватает?
Тема, которая привела меня к этому эксперименту, такова: проверка типа 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 :()
-Wall
не содержит много параметров. -Wconversion
является одним из них и предупреждает о поведении, которое вас интересует.
В общем случае присвоения значения int
объекту char
компилятор не знает, находится ли int
вне диапазона char
.
Внимательно посмотрите на фактическое предупреждение:
warning: overflow in implicit constant conversion
В этом конкретном случае, когда константа преобразуется в char
, что компилятор может вас предупредить. Аналогично, если вы изменили объявление i
на const
:
const int i = 256;
вы также получите предупреждение, потому что значение, присвоенное c2
, является константным выражением.
Обратите также внимание, что предупреждение несколько вводит в заблуждение, поскольку преобразование технически не "переполняется". Арифметическое переполнение дает поведение undefined в С++. Сужение преобразования (например, int
to char
, если int
имеет больший диапазон, чем char
), дает некоторое преобразование, определенное реализацией.
Ну, строка 5 - очевидная ошибка, которую может видеть любой компилятор напрямую, и всегда ошибка. Для обнаружения ошибки для строки 4 потребуется не менее некоторый анализ потока данных. Возможно, это не сделано с настройками, используемыми на сайте, или, возможно, авторы компилятора не считают это достаточно важным, чтобы понять это.
Опубликовать GCC 4.3, семантика -Wconversion
была обновлена, чтобы обнаружить неявные преобразования, которые могут изменить значение, но вам также нужно включить -Wsign-conversion
, потому что в противном случае вы не получите предупреждение для кода, который может изменить знак числа из-за принуждения между подписанными и неподписанными типами.
В отличие от того, что говорит Crazy Eddie, до GCC 4.3 (который еще не был выпущен в то время) -Wconversion
не проверил в целом проблемы, вызванные неявным преобразованием типа и т.п. Скорее, он проверил, будет ли ваша программа вести себя иначе, чем это было бы, если бы она использовала прототипы функции K & R старого стиля.
Это не только означало, что оно не давало предупреждения о всех неявных проблемах преобразования/принуждения типа, но это также означало, что некоторый хороший код дал ненужное предупреждение. И, конечно же, вы не получите ошибки с g++
, потому что такие прототипы в любом случае недействительны С++.