#c #if-statement #comparison #unsigned-integer
Вопрос:
Не могли бы вы объяснить, почему следующий код дает такие результаты?
#include <iostream>
int main()
{
int x = -1;
unsigned int y = 1;
if (x > y)
std::cout << "true";
else
std::cout << "false";
}
Вывод = true
но почему ?
Комментарии:
1. пожалуйста, по одному вопросу на вопрос. Они связаны, но все же 2 отдельных вопроса
2. Читайте о неявных преобразованиях
3.
x > y
становитсяstatic_cast<unsigned int>(x) > y
.4. @TedLyngmo Спасибо, я прочитаю об этой теме
5. Вот почему в C 20 появились утилиты для смешанных сравнений en.cppreference.com/w/cpp/utility/intcmp
Ответ №1:
Здесь происходит неявное преобразование из int
в unsigned int
, которое происходит следующим образом.
int x = -a;
unsigned int y = x; //As far as y can hold only positive values,
//it now holds UINT_MAX - (a 1)
Где UINT_MAX
находится макрос, который определен как максимальное значение unsigned int
, которое может содержаться.
В вашем случае x
преобразуется в UINT_MAX
, что, очевидно, больше 1
Ответ №2:
Что здесь происходит, так это то, что этот код:
int x = -1;
unsigned int y = 1;
bool result = x > y;
преобразуется в:
int x = -1;
unsigned int y = 1;
bool result = operator>(x, y);
Определены две функции operator> :
bool operator>(int, int);
bool operator>(unsigned int, unsigned int);
Но ты звонишь operator>(int, unsigned int)
. Таким образом, компилятор преобразовал ваш int со знаком в int без знака, а затем вызвал operator>(unsigned int, unsigned int)
, что привело к ошибке.
Стандартный способ избежать этого-включить предупреждения компилятора. Вы можете использовать предупреждение-Wconversion, которое предупредит вас об этой конкретной проблеме, или, что еще лучше, пройти через стену, чтобы включить все предупреждения.
Чтобы исправить ошибку в коде, вы можете явно указать компилятору, как преобразовать аргументы в оператор сравнения
#include <iostream>
int main()
{
int x = -1;
unsigned int y = 1;
if (x > static_cast<int>(y))
std::cout << "true";
else
std::cout << "false";
}
Но будьте осторожны с этим, так как это все равно может привести к ошибке, если ваш unsigned int больше, чем число, которое может поместиться в int. Самое безопасное решение-это если вы сможете сделать так, чтобы обе переменные были одного типа с самого начала.