我有以下代码示例(可以完全代表实际代码),并且试图使编译器不对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
中的用法在the godbolt output上看到的getVal
中的值不需要。
我了解到指针比较是一种“奇怪”的情况,编译器通常会采用“安全”路线而不进行优化,但是还有其他方法可以让编译器不发出这些检查,而实际上没有从getVal
中删除支票?