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