“静态计数器”为类型行为奇怪

编程入门 行业动态 更新时间:2024-10-09 13:23:53
本文介绍了“静态计数器”为类型行为奇怪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在开发一个基于实体的组件系统,我正在为组件类型分配一个特定的索引:

static std :: size_t getNextTypeId(){ static std :: size_t lastTypeIdBitIdx {0}; ++ lastTypeIdBitIdx; //这行产生问题结尾的输出 std :: cout<< lastTypeIdBitIdx<< std :: endl; return lastTypeIdBitIdx; } //假设TypeIdStorage< T1> :: bitIdx总是不同的 // TypeIdStorage< T2> :: bitIdx template< ;类型名称T> struct TypeIdStorage { static const std :: size_t bitIdx; }; //这行静态初始化bitIdx,得到下一个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 {...}; //等等...

在我的实体系统代码中,我使用 TypeIdStorage< T> :: bitIdx 与 T 几次组件类型之一 - 我期望这种情况发生: p>

  • 如果 TypeIdStorage< T> 存在,只需返回 TypeIdStorage< T> :: bitIdx 。
  • 如果不存在,请创建并初始化 bitIdx getNextTypeId()。

这是我运行应用程序时打印的内容:

1 2 3 1 2 3 4 5 6 7 $ b b 8 9 10 11 12 13 14 15 16 ...

如何调用 getNextTypeId()返回相同的数字?这种输出应该是不可能的。

不是保证静态变量会不断重复而增加?我真的很困惑这里。

使用 g ++ 4.8.1 和 clang ++ 3.4 ,都在 debug 和 release 模式。相同的输出。

valgrind 不打印任何有趣的东西。

clang ++ AddressSanitizer 不打印任何有趣的东西。

设置我的程序的入口点 int main(){return 0; } 产生完全相同的输出。问题是在编译时 - 但是怎么可能呢?

解决方案

您需要删除 static 时声明函数:

std :: size_t getNextTypeId(){ // ... }

以确保此函数只有一个版本。为此,你可能还需要将定义移动到一个实现文件,并且只在标题中留下声明。

如果你声明函数 static ,则表示该符号未导出,只能在同一翻译单元中使用。它不再在翻译单元之间共享。这导致每个翻译单元具有其自己的功能的副本,并且每个副本当然具有其自己的计数器。

I'm developing an entity-based component system, and I'm trying to assign a certain index to component types:

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()};

In my game code I have about 20 component types declared like this:

struct CPhysics : public sses::Component { ... }; struct CHealth : public sses::Component { ... }; struct CWeapon : public sses::Component { ... }; // and so on...

In my entity system code I use TypeIdStorage<T>::bitIdx with T being one of the component types several times - I expect this to happen:

  • If TypeIdStorage<T> exists, simply return TypeIdStorage<T>::bitIdx.
  • If it doesn't exist, create it and initialize bitIdx with getNextTypeId().

This is what is printed when I run the application:

1 2 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

How is it possible that calling getNextTypeId() returns the same number? This kind of output should be impossible.

Isn't it guaranteed that the static variable will get incremented without repeating? I'm truly confused here.

Tested both with g++ 4.8.1 and clang++ 3.4, both in debug and release modes. Same output.

valgrind does not print anything interesting.

clang++'s AddressSanitizer does not print anything interesting either.

Setting my program's entry point to int main() { return 0; } produces exactly the same output. The issue is at compile-time - but how is it possible? This seems like an impossible situation to me.

解决方案

You need to drop the static when declaring the function:

std::size_t getNextTypeId() { // ... }

to make sure only one version of this function exists. For this, you probably also need to move the definition to an implementation file and only leave the declaration in the header.

If you declare the function static, it means that the symbol is not exported and can only be used in the same translation unit. It is no longer shared between the translation units. This leads to each translation unit having its own copy of the function and each copy has, of course, its own counter.

更多推荐

“静态计数器”为类型行为奇怪

本文发布于:2023-10-18 15:27:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1504628.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:静态   计数器   奇怪   类型

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!