Почему компилятор не дает ошибку, когда значение знака присваивается беззнаковому целому? - С++

Я знаю, что 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.