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. JavaScript插件架构

    1.HTML布局规则 默认情况下,所有的插件都可以通过设置特定的HTML代码和相应的属性来实现.也就是说,在网页加载的时候,JavaScript代码会自动检测这些标记,并自动绑定相应的事件,而无需添加 ...

  2. ucenter 整合外部网站,实现登录等操作

    最近公司网站要出手机版,由于与论坛要有互通,实现会员的共享,由于对discuz不熟悉,起先考虑的是直接读取discuz的用户表,然后进行判断等操作,发现过于复杂,而且安全也不好. 前一段时间进行过论坛 ...

  3. 转来的。。。 关于return 的一些事情

    转来的 http://blog.csdn.net/haiwil/article/details/6691854/ 一般的来说,函数是可以返回局部变量的. 局部变量的作用域只在函数内部,在函数返回后,局 ...

  4. 随便2--struct pointer

    同为struct,如果struct中没有指针, C 和C++可以用等号赋值,但是一旦里面涉及到指针,就不能用等号,要用memcpy struct A{char v1[20];int v2;} a,b; ...

  5. Zerojudge解题经验交流

    题号:a001: 哈囉 背景知识:输出语句,while not eof 题号:a002: 簡易加法 背景知识:输出语句,while not eof,加法运算 题号:a003: 兩光法師占卜術 背景知识 ...

  6. Install FFMPEG and FFMPEG-PHP in CentOS 6 with Virtualmin

    Install FFMPEG and FFMPEG-PHP in CentOS 6 with Virtualmin  1 year ago -  by Daniel -  howto centos v ...

  7. 重置SQL Server连接池

    EXEC sp_configure 'show advanced options', 1 GO -- To update the currently configured value for adva ...

  8. Android事件分发机制(二)30分钟弄明白Touch事件分发机制

    Touch事件分发中只有两个主角:ViewGroup和View.Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理. View在 ...

  9. 在silverlight中通过WCF连接ORACLE DB数据库(转)

    转自 http://hi.baidu.com/qianlihanse/item/458aa7c8d93d4e0cac092ff4 这不是我的原创,我也是上网学习的~ How to get data f ...

  10. 【Linux】netdata监控组件

    github:https://github.com/firehol/netdata 安装:https://github.com/firehol/netdata/wiki/Installation 内存 ...