如果有一个函数将指针struct作为参数,并且函数有一个循环,在每次迭代时访问一个成员,如:
int function_a(struct b *b)
{
    // ... do something then
    for(int i = 0; i < 500; ++i){
        b->c->d[i] = value();
    }
}
它是否会每次检索c指向的位置和d指向内存?
现在考虑以下情况:
int function_a(struct b *b)
{
    // ... do something then
    float *f = b->c->d;
    for(int i = 0; i < 500; ++i){
        f[i] = value();
    }
}
会更快吗?
我敦促你注意托马斯马修斯关于剖析的建议,但要回答你的问题:这取决于你.
这种特殊的转换也称为代码提升,它包括移动代码而没有副作用,并且在循环外的每次调用时具有相同的结果.如上所述,只有在编译器可以证明:
在这两种情况下,这基本上意味着编译器应该可以访问两者的完整代码(参见定义):
因此,它实际上不太可能执行优化,除非所有身体循环的代码都包含在头文件中(因此可以内联),因为任何不透明的函数都可以b->c通过邪恶的全局变量隐藏(例如)修改.
在你的例子中,没有任何证据证明value()不会改变b->c......所以不,编译器提升代码是错误的,除非它能够访问定义value()并且可以排除这种可能性.