我正在开发一个基于实体的组件系统,并且我正在尝试为组件类型分配某个索引:
static std::size_t getNextTypeId() {
static std::size_t lastTypeIdBitIdx{0};
++lastTypeIdBitIdx;
// This line produces the output at the end of the question
std::cout << lastTypeIdBitIdx << std::endl;
return lastTypeIdBitIdx;
}
// I'm assuming that TypeIdStorage<T1>::bitIdx will always be different
// from TypeIdStorage<T2>::bitIdx
template<typename T> struct TypeIdStorage {
static const std::size_t bitIdx;
};
// This line statically initializes bitIdx, getting the next id
template<typename T> const std::size_t TypeIdStorage<T>::bitIdx{getNextTypeId()};
在我的游戏代码中,我声明了大约 20 个组件类型,如下所示:
struct CPhysics : public sses::Component { ... };
struct CHealth : public sses::Component { ... };
struct CWeapon : public sses::Component { ... };
// and so on...
在我的实体系统代码中,我多次使用作为组件类型之一 - 我希望这会发生TypeIdStorage<T>::bitIdx
:T
- 如果
TypeIdStorage<T>
存在,只需返回TypeIdStorage<T>::bitIdx
。 - 如果它不存在,则创建它并
bitIdx
使用getNextTypeId()
.
这是我运行应用程序时打印的内容:
1 2 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
呼叫怎么可能getNextTypeId()
返回相同的数字?这种输出应该是不可能的。
难道不能保证静态变量不会重复递增吗?我在这里真的很困惑。
在调试和发布模式下都使用g++ 4.8.1和clang++ 3.4进行了测试。相同的输出。
valgrind不会打印任何有趣的东西。
clang++ 的AddressSanitizer也不打印任何有趣的东西。
将我的程序的入口点设置为int main() { return 0; }
产生完全相同的输出。问题出在编译时——但怎么可能呢?这对我来说似乎是一个不可能的情况。