Предупреждение: переполнение при неявном преобразовании констант - PullRequest
15 голосов
/ 23 февраля 2011

В следующей программе строка 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 :()

Ответы [ 4 ]

12 голосов
/ 23 февраля 2011

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

См. http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

9 голосов
/ 23 февраля 2011

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

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

warning: overflow in implicit constant conversion

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

const int i = 256;

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

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

1 голос
/ 23 февраля 2011

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

0 голосов
/ 18 сентября 2017

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...