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 бита вы получите переполнение целочисленного со знаком (что является неопределенным поведением), тогда как на платформах, на которых