Почему компилятор не выдает ошибку, когда знаковое значение присваивается беззнаковому целому числу?- С++
-
12-09-2019 - |
Вопрос
Я знаю беззнаковое целое число не может содержать отрицательные значения.Но следующий код компилируется без каких-либо ошибок/предупреждений.
unsigned int a = -10;
Когда я печатаю переменную а, я получаю неправильное значение.Если беззнаковые переменные не могут содержать значения со знаком, почему компиляторы позволяют им компилироваться без каких-либо ошибок/предупреждений?
Есть предположения?
Редактировать
Компилятор:VС++-компилятор
Решение
Необходимо использовать уровень предупреждения 4.
Решение
Microsoft Visual С++:
предупреждение C4245:«инициализация»:Преобразование из «int» в «unsigned int», подписанное/безписанное несоответствие
На уровне предупреждения 4.
Г++
Дает мне предупреждение:
предупреждение:конвертация отрицательного значения
-0x00000000a' to
беззнаковое целое'
Без каких-либо директив -W.
GCC
Вы должны использовать:
gcc main.c -Wconversion
Что выдаст предупреждение:
предупреждение:отрицательное целое число, неявно преобразованное в беззнаковый тип
Обратите внимание, что -Wall не включит это предупреждение.
Возможно, вам просто нужно повысить уровень предупреждений.
Другие советы
Преобразование signed int
для unsigned int
это то, что известно в стандарте C как «Обычное арифметическое преобразование», поэтому это не ошибка.
Причина, по которой компиляторы часто не выдают предупреждение об этом по умолчанию, заключается в том, что это так часто делается в коде, что в целом будет выдано слишком много «ложных срабатываний».Существует очень много кода, который работает с signed int
значения для работы с вещами, которые по своей сути являются беззнаковыми (например, вычисление размеров буфера).Также очень часто в выражениях смешивают знаковые и беззнаковые значения.
Это не значит, что эти «тихие» преобразования не являются причиной ошибок.Таким образом, возможно, было бы неплохо включить предупреждение о новом коде, чтобы он был «чистым» с самого начала.Однако я думаю, что вам, вероятно, покажется довольно утомительным иметь дело с предупреждениями, выдаваемыми существующим кодом.
-10 анализируется как целочисленное значение, и допускается присвоение int беззнаковому int.Чтобы понять, что вы делаете что-то не так, компилятор должен проверить, является ли ваше целое число (-10) отрицательным или положительным.Поскольку это больше, чем просто проверка типа, я предполагаю, что она была отключена из-за проблем с производительностью.
Для компилятора gcc вы можете добавить
gcc -Wconversion ...
И это приведет к следующему предупреждению
warning: converting negative value '-0x0000000000000000a' to 'unsigned int'
Я использую g++ 4.9.2, и мне нужно использовать -Wsign-conversion, чтобы появилось это предупреждение.
gcc.gnu.org:Предупреждения о преобразованиях между целыми числами со знаком и без знака по умолчанию отключены в C++, если только -Wsign-conversion не включен явно.