0

我有以下内联方法并在其他方法中多次调用它。具有 O2 优化的 vc 和 gcc 编译器是否能够注意到该值在调用方法中是固定的并且只评估一次?--indexAndFlag在这些方法中确实没有改变。-- 或者,也许为了线程安全,每次调用都会对其进行评估?

unsigned int indexAndFlag;
...

inline Index* index() const
{
    return (Index*)(indexAndFlag & ~1);
}

该代码仅适用于保护模式 x86 32/64 位架构,所以我希望,我可以假设sizeof(unsigned int) == sizeof(Index*). 如果没有,请纠正我。

4

2 回答 2

3

如果看起来indexAndFlag是一个非常量非静态全局,那么不是。编译器无法确定另一个翻译单元是否可以修改它,因此程序必须在任何使用它的地方访问它的值。

如果它是const,并且使用常量表达式初始化,那么编译器必须将其视为常量值,并且您的表达式也视为常量值。

我希望,我可以假设sizeof(unsigned int) == sizeof(Index*)

我不会:许多流行的 64 位架构都有 32 位int. 使用uintptr_t确定。

于 2013-09-19T11:20:46.557 回答
2

从底部开始:sizeof(unsigned int) != sizeof(Index *)在 64 位中,这是肯定的。如果你做出这样的假设,我肯定会建议你static_assert(sizeof(unsigned int) == sizeof(Index *))在代码中的某个地方使用。

接下来,编译器在全局变量和优化方面做什么或不做什么绝对是“由编译器决定”的情况。编译器可能会决定每次都重新加载该值,或者它可能会决定“啊,我知道这不会改变”。这实际上取决于它对indexAndFlag不变的“理解”的程度。

我个人会使用类似的东西:

 Index* temp = index();

  ... 
   use temp
  ...

然后保证不会进行额外的操作来“计算”索引。

于 2013-09-19T11:19:34.297 回答