Ответ 1
Так как тип операндов различен, происходит неявное преобразование для достижения общего типа.
Для бинарных операторов (кроме сдвигов), если повышенные операнды имеют разные типы, применяется дополнительный набор неявных преобразований, известных как обычные арифметические преобразования, с целью создания общего типа (также доступного через черту типа std :: common_type)
из-за целочисленных типов здесь применяются интегральные преобразования:
- Если один из операндов имеет тип перечисления с областью действия, преобразование не выполняется: другой операнд и возвращаемый тип должны иметь одинаковые
тип
- В противном случае, если один из операндов long long, другой операнд преобразуется в long double
- В противном случае, если один из операндов является двойным, другой операнд преобразуется в двойной
- В противном случае, если один из операндов является float, другой операнд преобразуется в float
- В противном случае операнд имеет целочисленный тип (потому что перечисление bool, char, char8_t, char16_t, char32_t, wchar_t и unscoped перечислено в этой точке), и интегральные преобразования применяются для получения общего типа следующим образом:
- Если оба операнда подписаны или оба без знака, операнд с меньшим рангом преобразования преобразуется в операнд с большим целым рангом преобразования
- В противном случае, если ранг преобразования беззнакового операнда больше или равен рангу преобразования подписанного операнда, подписанный операнд преобразуется в беззнаковый
тип операнда.- В противном случае, если тип операнда со знаком может представлять все значения беззнакового операнда, беззнаковый операнд преобразуется в тип операнда со знаком. В противном случае оба операнда преобразуются в беззнаковый аналог типа операнда со знаком.
Те же арифметические преобразования применимы и к операторам сравнения.
из всего этого можно сделать вывод, что все rhs
равны uint8_t
общий тип будет int, а затем, поскольку rhs
равен uint32_t
общий тип оператора ==
будет uint32_t
. но по какой-то причине я понятия не имею, gcc
не выполняет последнее преобразование, пока clang делает это. смотрите преобразование типа gcc
для оператора +
в godblot. Также может случиться, что предупреждение является ложным предупреждением, и преобразование произошло, как это произошло для оператора +
. Посмотрите, как clang
видит последнее if
(cppinsights):
if(foo == static_cast<unsigned int>(static_cast<int>(a) + (static_cast<int>
(b) * static_cast<int>(c))))
Обновить:
Я не смог найти разницы в сборке, сгенерированной двумя компиляторами, и согласился бы с @MM, так что, IMO, это ошибка gcc
.