Почему современные C/C++ компиляторы не умеют как следует в оптимизацию функций с побочным эффектом? Взять например такой код
#include <inttypes.h>
#include <stdbool.h>
uint32_t test(uint8_t a)
{
static uint32_t lookup[255] = {0};
if (a == 0) return 0;
if (lookup[a-1] != 0 ) return lookup[a-1];
uint32_t tmp = a;
tmp = tmp * tmp * tmp * tmp;
lookup[a-1] = tmp;
return tmp;
}
bool test2(uint8_t a)
{
return test(a) == test(a);
}
test2
. Если просто скомпилить это дело без всяких заморочек, компилятор дважды заинлайнит код функции test
внутрь test2
. Если сделать uint32_t test(uint8_t) __attribute__ ((noinline));
то функция будет вызвана дважды, и потом результаты будут сравниваться. А если сделать: uint32_t test(uint8_t) __attribute__ ((pure));
и компилить с -Os
то в итоге код функции test2
свернется в аналог return 1;
и никакой мемоизации я при этом не получу (см. http://goo.gl/YQNc8B )- это не то, что я хочу получить.Так вот, к чему это я. Вопрос: возможно ли как-нибудь «убедить» существующе C(желательно) или на C++(нежелательно) компиляторы, чтобы они мне нормальную мемоизацию делали? Чтобы у меня в данном примере из функции test2
ОДИН РАЗ или вызывалась функция test
(записывая или не записывая число в lookup
массив) и возвращался 1 или чтобы инлайнил кусок кода из функции лишь единожды, для записи в static массив и чтобы возвращал 1; Я думал насчет того чтобы создать свой язык программирования и «компилировать» его в исходик C и потом его компилить C компилятором, но если компиляторы такие вещи не оптимизируют, мне придется лезть в SSA, LLVM и прочие подобные вещи, а такая перспектива меня не радует