Оптимизация компилятора C ++ для сравнения линейных указателей - PullRequest
0 голосов
/ 31 января 2019

У меня следующий пример кода (довольно представительный для реального кода), и я пытаюсь заставить компилятор не генерировать сравнения для встроенных проверок индекса в getVal (строка 32).

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

using TValue = uint32_t;

struct CI {
    TValue* func;
};

struct LS {
    TValue* top;
    CI* ci;
};

LS* makeState() {
    auto s = new LS();
    s->ci = new CI();
    s->ci->func = new TValue[4];
    s->top = &s->ci->func[3];
    return s;
}

inline int assertTop(LS* s, int idx) {
    const TValue* o = s->ci->func + idx;

    return ((uintptr_t)o <= (uintptr_t)s->top) ? 1 : 0;
}

inline uint32_t getVal(LS* s, int idx) {
    const TValue* o = s->ci->func + idx;

    if (o >= s->top) {
        return -1;
    }

    return *o;
}

void check(LS* s) {
    if (assertTop(s, 3)) {
        printf("%d %d %d", getVal(s, 0), getVal(s, 1), getVal(s, 2));
    }
}

int main()
{
    auto s = makeState();
    check(s);

    return 0;
}

Практически, так как этот код не может быть достигнут, если сравнение в assertTop завершается неудачно, и никакой другой код с побочными эффектами не выполняется, эти дополнительные проверки (испускаемые при использовании check getVal как видно на вывод Godbolt ) не нужен.

Я понимаю, что сравнение указателей - это "странный" сценарий, для которого компиляторы обычно выбирают "безопасный" маршрут ине оптимизировать, но есть ли другой способ заставить компилятор не выдавать эти проверки, фактически не удаляя проверку из getVal?

...