Компилятор независимое выражение арифметические преобразования и целочисленные продвижения
Предположим, у нас есть присваивание с использованием переменных следующих типов:
uint64 = uint16 + uint16 + uint32 + uint64
Предположим, мы знаем, что результирующее значение r вписывается в uint64, если вся работа выполняется с использованием uint64.
Будет ли компилятор неявно продвигать два uint16 и uint32 в uint64 ДО выполнения каких-либо вычислений в соответствии со стандартными правилами C?
т.е.
1.) uint64 = uint16 + uint16 + uint32 + uint64
2.) uint64 = uint64 + uint64 + uint64 + uint64
В частности, применяя второе утверждение в следующем фрагменте:
Если оба операнда имеют одинаковый тип, дальнейшее преобразование не требуется.
В противном случае, если оба операнда имеют целочисленные типы со знаком или оба имеют целочисленные типы без знака, операнд с типом ранга преобразования с меньшим целым числом преобразуется в тип операнда с большим рангом.
В противном случае, если операнд с целым типом без знака имеет ранг, больший или равный рангу типа другого операнда, тогда операнд с целым типом со знаком преобразуется в тип операнда с целым типом без знака.
В противном случае, если тип операнда с целочисленным типом со знаком может представлять все значения типа операнда с целочисленным типом без знака, тогда операнд с целочисленным типом без знака преобразуется в тип операнда с целочисленным типом со знаком.
В противном случае оба операнда преобразуются в тип целого без знака, соответствующий типу операнда с целым типом со знаком.
Или же это правило применяется только к непосредственным значениям lhs и rhs арифметического выражения, так что добавление двух uint16 может быть сначала вычислено там, где типы не будут продвигаться до тех пор, пока не будет известен результат, а затем оно будет повышено до uint32, затем этот результат повышен до uint64 и т.д...
т.е.
1.) uint64 = uint16 + uint16 + uint32 + uint64
2.) uint64 = (((uint16 + uint16) + uint32) + uint64)
3.) uint64 = ((uint32 + uint32) + uint64)
4.) uint64 = (uint64 + uint64)
Пожалуйста, укажите мне на любые стандартные правила C, которые могут прояснить это для меня.
1 ответ
Правило применяется к промежуточному результату:
uint16 + uint16 + uint32 + uint64
эквивалентно
((uint16 + uint16) + uint32) + uint64
и обычные арифметические преобразования выполняются по обе стороны от +
оператор.
(C99, 6.5.6 Аддитивные операторы p4) "Если оба операнда имеют арифметический тип, для них выполняются обычные арифметические преобразования".
Обратите внимание, что при условии 32-bit
int
, это на самом деле так же, как:
(uint64) ((unsigned int) ((int) uint16 + (int) uint16) + uint32) + uint64
uint16
повышен до int
не для unsigned int
, а затем результат преобразуется в unsigned int
потому что uint32
,