Я заметил, что код ниже, скомпилированный с clang 11.0.3, дает другой результат, когда я использую флаг -O0 и -O3.
#include <stdio.h>
#include <inttypes.h>
int64_t foo(int64_t a, int32_t b, int32_t c) {
const int32_t p1 = 7654321;
const int32_t p2 = 8765432;
const int64_t p3 = 1234567LL;
const int32_t p4 = 987654;
const int64_t e = a + b * b * p1 + b * p2 + c * c * p3 + c * p4;
return e;
}
int main(void) {
const int64_t a = 1234LL;
int32_t b = 130;
int32_t c = -148;
printf("%lld\n", foo(a, b, c)); // -O0: 28544296190, -O3: 28544296190
b = 167;
c = -93;
printf("%lld\n", foo(a, b, c)); // -O0: 10772740108, -O3: 15067707404
return 0;
}
Первый результат тот же, но второй отличается. Я думал, что это происходит из-за неявного преобразования типов. Я скомпилировал код в сборку с флагом -O0, чтобы увидеть, в каком порядке выполняются все вычисления. В соответствии с этим я добавил явное приведение и скобки в функцию foo:
const int64_t e = (((a + (int64_t)(b * b * p1)) + (int64_t)(b * p2)) + (int64_t)((int64_t)(c * c) * p3)) + (int64_t)(c * p4);
Это не помогло, хотя я действительно не знаю, как это исправить. Как должен выглядеть код для правильной работы с оптимизацией O3?