FName是unreal3里对字符串高效处理的一种机制

基本原理就是把字符串hash存起来,然后每个字符串就只需要用一个数组索引值来表示了

FName的属性:

NAME_INDEX Index;

INT Number;

Index就是数组索引,Number是一种特殊用途:系统在生成对象时通常会规律自动起名,如Object_12、Object_13、Object_14等等,若每一个都单独保存就很浪费,FName会把它末尾的数字拆开,只对前半节做hash保存,这样三个名字得到的Index值都一样了,而不一样的数字部分则存在Number里。

FName的实例属性也就这两个,其它都是静态成员了,就是数组和hash表:

/** Table of all names. This is a NoInit because we may need to use it before the constructor is called due to random static variable initialization order */
static TArrayNoInit<FNameEntry*> Names;
/** Name hash. */
static FNameEntry* NameHash[ FNameDefs::NameHashBucketCount ];

其中Names就是所有FName按先来后到顺序存放的数组,当要从一个FName获取其FString时,就是通过Names[Index]->AnsiName来访问了

而NameHash则是用来快速查找的hash表,其索引就是各字符串的hash值。

然而这个hash值的计算是忽略大小写的,这就导致一个大问题:

FName居然是不区分大小的!

就算UnrealEngine内部自己约定,所有名字变量都不区分大小写,也仍然有问题,因为,C++语言本身是区分大小写的!

我就碰到过一个这样的bug:

当重新编译脚本并生成C++头文件时,FURL里有一个字段Host,在脚本定义时明明是大写,可是一生成C++代码就成了小写,按理说这是相当基础的内部类,我根本就不可能改到它,为什么它会自己变样呢?如果我尝试把它名字改成Host2之类的,它就不会变小写了。

经过一连串的跟踪,终于在调试器的帮助下找到了原因:因为在解析uc文件里的每一句变量声明时,都会用一个FName来保存读到的变量名,而如果这串字符之前已经有遇到过,那么无论其大小写是否一样,都会认为是同一个值并使用之前已经存储的版本,而此次的真实值就被抛弃了。恰好我在INI文件里定义了一个host=XXXX的属性对,由于加载INI在前,解析脚本类在后,所以当解析到FURL结构里的Host字段时,发现FName::Names里已经有了一个小写的host项,就直接把它当作变量名使用了!然而C++编译器可是区分大小写的,原来代码里那么使用Host的地方,在小写的新版头文件下,肯定编译出错。

解决的办法,当然只能是去修改INI里的Key了,然而这真的是一个非常隐蔽的BUG啊,哪天又一不小心重名了,分分钟跳坑。。。

unreal3之FName及潜在bug的更多相关文章

  1. Session 潜在bug防范

    注意: Session的使用一定要及时的清理,因为它是“全局”的(包括其生命周期),所以在使用Session保存状态时,不用时要及时的NULL掉,小心潜在的Bug.

  2. Java-idea-FindBugs字节码级别潜在bug查看

    一.概述 静态分析工具承诺无需开发人员费劲就能找出代码中已有的缺陷. FindBugs 不注重样式或者格式,它试图只寻找真正的缺陷或者潜在的性能问题. FindBugs 是一个静态分析工具,它检查类或 ...

  3. Java-idea-PMD源文件级别潜在bug查看

    一.概述 PMD(Project Manager Design)是一种开源分析Java代码错误的工具.与其他分析工具不同的是,PMD通过静态分析获知代码错误.也就是说,在不运行Java程序的情况下报告 ...

  4. 检测代码潜在bug和质量之SonarQube

    参数使用 项目分析参数可以在多个地方设置,继承关系如下: 全局分析参数,通过Web UI设置,作用于所有项目(配置–>通用–>通用中设置) 项目分析参数,通过WebUI设置,覆盖全局参数( ...

  5. 添加PMD插件扫描潜在的bug

    上一节使用checkstyle来规范你的项目主要解决了代码编码规范问题,比如缩进换行等.这次继续代码健康工具类PMD. 什么是PMD PMD真的不像checkstyle这样的东西所见即所得啊,去官网找 ...

  6. Erlang 程序引发共享内存 bug 的一个例子

    虽然 Erlang 的广告说得非常好,functional.share-nothing.消息传递,blah blah 的,好像用 Erlang 写并发程序就高枕无忧了,但是由于 Erlang 信奉高度 ...

  7. 实际例子描述和分析“猎豹抢票跨站推荐功能有票刷不到”的疑似bug

    前言 快过年了,又到了一年抢票时.今年douba和douma计划要带着doudou回姥姥家.昨天在家用抢票软件居然发现了一个bug,那就是在猎豹抢票中跨站推荐的车票几天里一直是没有,但是在12306手 ...

  8. 关于C/C++语言的部分BUG

    目录 scanf格式匹配引发的错误 局部变量被释放引发的bug 数组写入超出索引维度 指针的指针引发的思考 未定义赋值的变量引发的bug 题外话 scanf格式匹配引发的错误   运行如下程序时,出现 ...

  9. UVa 658 - It's not a Bug, it's a Feature!(Dijkstra + 隐式图搜索)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

随机推荐

  1. OneNote 2013 快捷键

    越来越喜欢onenote这个笔记本软件,找了下提高效率的办法,收藏学习下: 转载自:http://onenoter.com/2013/04/5792 记录笔记和设置笔记格式 键入和编辑笔记 操作 按键 ...

  2. java 网络编程复习(转)

    好久没有看过Java网络编程了,现在刚好公司有机会接触,顺便的拾起以前的东西 参照原博客:http://www.cnblogs.com/linzheng/archive/2011/01/23/1942 ...

  3. Java事务处理全解析(五)—— Template模式

    在本系列的上一篇文章中,我们讲到了使用TransactionManger和ConnectionHolder完成线程安全的事务管理,在本篇中,我们将在此基础上引入Template模式进行事务管理. Te ...

  4. 源码阅读笔记 - 1 MSVC2015中的std::sort

    大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...

  5. eclipse将编辑栏一分为二

    今天无意中发现一个MyEclipse的功能,CTRL SHIF - 三个键一起按下时,同一个编辑窗口会一分为二.这样我们写下面代码需要参考前面代码的时候就很方便了.

  6. HTTP调试工具扩展

    ★Fiddler神器之一,IE-WinNet-Fiddler-Server,能跟踪调试HTTP和HTTPS是优点也是缺点. 地址:http://www.fiddler2.com/ ★Charles,可 ...

  7. No.5__C#

    One month 今天是个有纪念意义的日子,2015-4-23.今天是实习的第一个月,算是成就达成吧.虽然,除去了周末六日和清明什么的,只剩下20多天了,但是,还是好开心 啊,毕竟是第一次参加工作, ...

  8. AX 2012 关于parts 添加

    只有当引用parts的form中design属性style为 ListPage, DetailsFormMaster, or DetailsFormTransaction,才能创建FactBox pa ...

  9. 神奇的C语言

    当然下面列出来的几点都是C的基础用法,只不过是这些用法可能平时不会被注意.所以很多东西第一次看到的时候,可能会觉得很怪异,但是细细想想就能很好的理解,也就能更好的清楚C语言的一些特性.但是在具体的编码 ...

  10. Android IOS WebRTC 音视频开发总结(七一)-- H265/H264有何不同

    本文整理自自网络,非原创,喜欢相关文章请关注我们的微信公众号:blackerteam H.265 H.265是ITU-TVCEG继H.264之后所制定的新的视频编码标准.H.265标准围绕着现有的视频 ...