C: Неопределенное поведение при умножении uint16_t?

Я понял и прочитал, что умножение a на другоеuint16_tприводит к целому числу (на самом деле оно кажется целым числом со знаком? см.: ). Учитывая это, должен ли я предполагать, что следующая функцияfпроизводит неопределенное поведение, потому что будет переполнение целого числа со знаком?

Произойдет переполнение, потому что для результатов будет "почти", и тогда оно переполнится, если его снова умножить на .

(кстати: на моей платформеintэтоint32_t)

      #include <stdio.h>
#include <stdint.h>

uint16_t f(uint16_t x) {
    printf("%zu\n", sizeof(x));     // <-- 2
    printf("%zu\n", sizeof(x * x)); // <-- 4
    return x * x * x;
}

int main()
{
    uint16_t x = 45000;
    uint16_t y = f(x);
}

Произойдет переполнение, потому чтоx*xдляx=45000получается "почти"INT32_MAXи затем он переполнится, если его снова умножить наx.

Это правильно, или я делаю какие-то неправильные предположения?

1 ответ

Вы правы в том, что ваш опубликованный код вызовет неопределенное поведение из-за переполнения целого числа со знаком.

В соответствии с §6.3.1.1 ¶2 стандарта ISO C11 оба операнда будут повышены до , потому что на вашей платформе 32-битная ширина и поэтому может представлять все значения, представляемые. Если бы это было не так, то операнды были бы повышены до.

Следовательно, на платформах с шириной 32 бита вы получите переполнение целочисленного со знаком (что является неопределенным поведением), тогда как на платформах, на которыхимеет ширину 16 бит, вы получите переполнение целого числа без знака (что не является неопределенным поведением).

Другие вопросы по тегам